def test_toggle_badge_on(self, cli): org = OrganizationFactory() cli('badges', 'toggle', str(org.id), PUBLIC_SERVICE) org.reload() assert org.badges[0].kind == PUBLIC_SERVICE
def test_org_admin_can_accept_transfer(self): owner = UserFactory() admin = UserFactory() org = OrganizationFactory(members=[Member(user=admin, role='admin')]) subject = VisibleDatasetFactory(owner=owner) transfer = TransferFactory(owner=owner, recipient=org, subject=subject) owner.reload() # Needs updated metrics assert owner.metrics['datasets'] == 1 org.reload() # Needs updated metrics assert org.metrics['datasets'] == 0 admin.reload() # Needs updated metrics assert admin.metrics['datasets'] == 0 login_user(admin) transfer = accept_transfer(transfer) assert transfer.status == 'accepted' subject.reload() assert subject.organization == org assert subject.owner is None org.reload() assert org.metrics['datasets'] == 1 admin.reload() assert admin.metrics['datasets'] == 0 owner.reload() assert owner.metrics['datasets'] == 0
def test_toggle_badge_off(self, cli): ps_badge = Badge(kind=PUBLIC_SERVICE) certified_badge = Badge(kind=CERTIFIED) org = OrganizationFactory(badges=[ps_badge, certified_badge]) cli('badges', 'toggle', str(org.id), PUBLIC_SERVICE) org.reload() assert org.badges[0].kind == CERTIFIED
def test_organizations_within_sitemap(self, sitemap): '''It should return an organization list from the sitemap.''' organizations = OrganizationFactory.create_batch(3) sitemap.fetch() for org in organizations: url = sitemap.get_by_url('organizations.show_redirect', org=org) assert url is not None sitemap.assert_url(url, 0.7, 'weekly')
def test_minimal(self): org = OrganizationFactory.build() # Does not have an URL o = organization_to_rdf(org) g = o.graph self.assertIsInstance(o, RdfResource) self.assertEqual(len(list(g.subjects(RDF.type, FOAF.Organization))), 1) self.assertEqual(o.value(RDF.type).identifier, FOAF.Organization) self.assertIsInstance(o.identifier, BNode) self.assertEqual(o.value(FOAF.name), Literal(org.name)) self.assertEqual(o.value(RDFS.label), Literal(org.name))
def swaggerui(): page_size = 10 params = {"datasets": "many"} organizations = search.iter(Organization) organizations = list(itertools.islice(organizations, page_size)) if len(organizations) < page_size: # Fill with dummy values needs = page_size - len(organizations) extra_orgs = OrganizationFactory.build_batch(needs) for org in extra_orgs: org.id = ObjectId() Organization.slug.generate() organizations.extend(extra_orgs) return theme.render('apidoc.html', specs_url=api.specs_url, organizations=organizations)
def test_my_org_reuses_with_search(self): user = self.login() member = Member(user=user, role='editor') organization = OrganizationFactory(members=[member]) reuses = [ ReuseFactory(owner=user, title='foô'), ] org_reuses = [ ReuseFactory(organization=organization, title='foô'), ] # Should not be listed. ReuseFactory(owner=user) ReuseFactory(organization=organization) response = self.get(url_for('api.my_org_reuses'), qs={'q': 'foô'}) self.assert200(response) self.assertEqual(len(response.json), len(reuses) + len(org_reuses))
def test_unfollow_org(self): '''It should unfollow the organization on DELETE''' user = self.login() to_follow = OrganizationFactory() Follow.objects.create(follower=user, following=to_follow) response = self.delete( url_for('api.organization_followers', id=to_follow.id)) self.assert200(response) nb_followers = Follow.objects.followers(to_follow).count() self.assertEqual(nb_followers, 0) self.assertEqual(response.json['followers'], nb_followers) self.assertEqual(Follow.objects.following(to_follow).count(), 0) self.assertEqual(Follow.objects.following(user).count(), 0) self.assertEqual(Follow.objects.followers(user).count(), 0)
def test_my_org_datasets_with_search(self): user = self.login() member = Member(user=user, role='editor') organization = OrganizationFactory(members=[member]) datasets = [ VisibleDatasetFactory(owner=user, title='foo'), ] org_datasets = [ VisibleDatasetFactory(organization=organization, title='foo'), ] # Should not be listed. VisibleDatasetFactory(owner=user) VisibleDatasetFactory(organization=organization) response = self.get(url_for('api.my_org_datasets'), qs={'q': 'foo'}) self.assert200(response) self.assertEqual(len(response.json), len(datasets) + len(org_datasets))
def test_suggest_organizations_by_id(self, api, autoindex): '''It should suggest an organization by its ID''' with autoindex: orgs = OrganizationFactory.create_batch(3) first_org = orgs[0] response = api.get(url_for('api.suggest_organizations'), qs={ 'q': str(first_org.id), 'size': '5' }) assert200(response) # The batch factory generates ids that might be too close # which then are found with the fuzzy search. suggested_ids = [u['id'] for u in response.json] assert len(suggested_ids) >= 1 assert str(first_org.id) in suggested_ids
def test_idempotence(self): filename = 'flat.jsonld' url = mock_dcat(filename) org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) # Run the same havester twice actions.run(source.slug) actions.run(source.slug) datasets = {d.extras['dct:identifier']: d for d in Dataset.objects} self.assertEqual(len(datasets), 3) self.assertEqual(len(datasets['1'].resources), 2) self.assertEqual(len(datasets['2'].resources), 2) self.assertEqual(len(datasets['3'].resources), 1)
def test_all_fields(self): org = OrganizationFactory(url=faker.uri()) org_url = url_for('organizations.show_redirect', org=org.id, _external=True) o = organization_to_rdf(org) g = o.graph self.assertIsInstance(o, RdfResource) self.assertEqual(len(list(g.subjects(RDF.type, FOAF.Organization))), 1) self.assertEqual(o.value(RDF.type).identifier, FOAF.Organization) self.assertIsInstance(o.identifier, URIRef) self.assertEqual(o.identifier.toPython(), org_url) self.assertEqual(o.value(FOAF.name), Literal(org.name)) self.assertEqual(o.value(RDFS.label), Literal(org.name)) self.assertEqual(o.value(FOAF.homepage).identifier, URIRef(org.url))
def test_supported_mime_type(self, rmock): url = mock_dcat(rmock, 'catalog.xml', path='without/extension') rmock.head(url, headers={'Content-Type': 'application/xml; charset=utf-8'}) org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() assert job.status == 'done' assert job.errors == [] assert len(job.items) == 3
def test_suggest_organizations_by_id(self): '''It should suggest an organization by its ID''' with self.autoindex(): orgs = OrganizationFactory.create_batch(3) first_org = orgs[0] response = self.get(url_for('api.suggest_organizations'), qs={ 'q': str(first_org.id), 'size': '5' }) self.assert200(response) # The batch factory generates ids that might be too close # which then are found with the fuzzy search. suggested_ids = [u['id'] for u in response.json] self.assertGreaterEqual(len(suggested_ids), 1) self.assertIn(str(first_org.id), suggested_ids)
def test_create_badge_public_service_mail(self): member = Member(user=self.user, role='admin') org = OrganizationFactory(members=[member]) data = self.factory.as_dict() data['kind'] = PUBLIC_SERVICE with self.capture_mails() as mails: self.post(url_for('api.organization_badges', org=org), data) # do it a second time, no email expected for this one self.post( url_for('api.organization_badges', org=self.organization), data) # Should have sent one mail to each member of organization members_emails = [m.user.email for m in org.members] self.assertEqual(len(mails), len(members_emails)) self.assertListEqual([m.recipients[0] for m in mails], members_emails)
def test_regions_with_other_datasets_logged_in(self): self.login() with self.autoindex(): organization = OrganizationFactory() VisibleDatasetFactory.create_batch( 3, organization=organization, spatial=SpatialCoverageFactory(zones=[self.paca.id])) response = self.client.get( url_for('territories.territory', territory=self.paca)) self.assert200(response) data = response.data.decode('utf-8') base_datasets = self.get_context_variable('base_datasets') self.assertEqual(len(base_datasets), 0) other_datasets = self.get_context_variable('other_datasets') self.assertEqual(len(other_datasets), 3) self.assertEqual(self.get_context_variable('territory_datasets'), []) self.assertIn('If you want your datasets to appear in that list', data)
def test_unfollow_org(self, api): '''It should unfollow the organization on DELETE''' user = api.login() to_follow = OrganizationFactory() Follow.objects.create(follower=user, following=to_follow) url = url_for('api.organization_followers', id=to_follow.id) response = api.delete(url) assert200(response) nb_followers = Follow.objects.followers(to_follow).count() assert nb_followers is 0 assert response.json['followers'] == nb_followers assert Follow.objects.following(to_follow).count() is 0 assert Follow.objects.following(user).count() is 0 assert Follow.objects.followers(user).count() is 0
def test_set_organization_if_permissions(self): Ownable, OwnableForm = self.factory() user = UserFactory() member = Member(user=user, role='editor') org = OrganizationFactory(members=[member]) ownable = Ownable(owner=user) login_user(user) form = OwnableForm(MultiDict({'organization': str(org.id)}), obj=ownable) self.assertTrue(form.validate()) self.assertEqual(form.errors, {}) form.populate_obj(ownable) self.assertIsNone(ownable.owner) self.assertEqual(ownable.organization, org)
def test_unsupported_mime_type(self, rmock): url = DCAT_URL_PATTERN.format(path='', domain=TEST_DOMAIN) rmock.head(url, headers={'Content-Type': 'text/html; charset=utf-8'}) org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() assert job.status == 'failed' assert len(job.errors) == 1 error = job.errors[0] assert error.message == 'Unsupported mime type "text/html"'
def test_suggest_organizations_with_multiple_words(self, api): '''It should suggest organizations with words''' for i in range(4): OrganizationFactory( name='mon testé-{0}'.format(i) if i % 2 else faker.word()) response = api.get(url_for('api.suggest_organizations'), qs={'q': 'mon testé', 'size': '5'}) assert200(response) assert len(response.json) <= 5 assert len(response.json) > 1 for suggestion in response.json: assert 'id' in suggestion assert 'slug' in suggestion assert 'name' in suggestion assert 'image_url' in suggestion assert 'mon testé' in suggestion['name']
def test_list_org_discussions(self, api): '''Should list organization discussions''' user = UserFactory() org = OrganizationFactory() reuse = ReuseFactory(organization=org) dataset = DatasetFactory(organization=org) discussions = [ Discussion.objects.create(subject=dataset, title='', user=user), Discussion.objects.create(subject=reuse, title='', user=user) ] response = api.get(url_for('api.org_discussions', org=org)) assert200(response) assert len(response.json) == len(discussions) discussions_ids = [str(d.id) for d in discussions] for discussion in response.json: assert discussion['id'] in discussions_ids
def test_with_old_region_datasets(self): lr, occitanie = create_old_new_regions_fixtures() with self.autoindex(): for region in [lr, occitanie]: organization = OrganizationFactory(zone=region.id) VisibleDatasetFactory.create_batch( 3, organization=organization, spatial=SpatialCoverageFactory(zones=[region.id])) response = self.client.get( url_for('territories.territory', territory=occitanie)) self.assert200(response) data = response.data.decode('utf-8') self.assertIn(occitanie.name, data) base_datasets = self.get_context_variable('base_datasets') self.assertEqual(len(base_datasets), 0) territory_datasets = self.get_context_variable('territory_datasets') self.assertEqual(len(territory_datasets), 3) territory_datasets = self.get_context_variable('other_datasets') self.assertEqual(len(territory_datasets), 3)
def test_create_source_with_org(self, api): '''It should create and attach a new source to an organization''' user = api.login() member = Member(user=user, role='admin') org = OrganizationFactory(members=[member]) data = { 'name': faker.word(), 'url': faker.url(), 'backend': 'factory', 'organization': str(org.id) } response = api.post(url_for('api.harvest_sources'), data) assert201(response) source = response.json assert source['validation']['state'] == VALIDATION_PENDING assert source['owner'] is None assert source['organization']['id'] == str(org.id)
def test_render_display_with_private_reuses(self): '''It should render the organization page with some private reuses''' me = self.login() member = Member(user=me, role='editor') organization = OrganizationFactory(members=[member]) reuses = [ReuseFactory(organization=organization) for _ in range(2)] private_reuses = [ VisibleReuseFactory(organization=organization, private=True) for _ in range(2) ] response = self.get(url_for('organizations.show', org=organization)) self.assert200(response) rendered_reuses = self.get_context_variable('reuses') self.assertEqual(len(rendered_reuses), 0) rendered_private_reuses = self.get_context_variable('private_reuses') self.assertEqual(len(rendered_private_reuses), len(reuses) + len(private_reuses))
def test_create_with_file_chunks(self): '''It should create a resource from the API with a chunked file''' user = self.login() with self.autoindex(): org = OrganizationFactory( members=[Member(user=user, role='admin')]) dataset = DatasetFactory(organization=org) uuid = str(uuid4()) parts = 4 url = url_for('api.upload_new_dataset_resource', dataset=dataset) for i in range(parts): response = self.post(url, { 'file': (StringIO(b'a'), 'blob'), 'uuid': uuid, 'filename': 'test.txt', 'partindex': i, 'partbyteoffset': 0, 'totalfilesize': parts, 'totalparts': parts, 'chunksize': 1, }, json=False) self.assert200(response) assert response.json['success'] assert 'filename' not in response.json assert 'url' not in response.json assert 'size' not in response.json assert 'sha1' not in response.json assert 'url' not in response.json response = self.post(url, { 'uuid': uuid, 'filename': 'test.txt', 'totalfilesize': parts, 'totalparts': parts, }, json=False) self.assert201(response) data = json.loads(response.data) self.assertEqual(data['title'], 'test.txt')
def test_unsupported_mime_type(self): url = DCAT_URL_PATTERN.format(path='', domain=TEST_DOMAIN) httpretty.register_uri(httpretty.HEAD, url, content_type='text/html; charset=utf-8') org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() self.assertEqual(job.status, 'failed') self.assertEqual(len(job.errors), 1) error = job.errors[0] self.assertEqual(error.message, 'Unsupported mime type "text/html"')
def test_oembed_region_territory_api_get(self): '''It should fetch a region territory in the oembed format.''' midi_pyrenees = GeoZoneFactory(id='fr/region/73', level='fr/region', name='Midi-Pyrénées', code='73') licence_ouverte = LicenseFactory(id='fr-lo', title='Licence Ouverte') LicenseFactory(id='notspecified', title='Not Specified') for territory_dataset_class in TERRITORY_DATASETS['region'].values(): organization = OrganizationFactory( id=territory_dataset_class.organization_id) territory = territory_dataset_class(midi_pyrenees) reference = 'territory-{id}'.format(id=territory.slug) response = self.get(url_for('api.oembeds', references=reference)) self.assert200(response) data = json.loads(response.data)[0] self.assertIn('html', data) self.assertIn('width', data) self.assertIn('maxwidth', data) self.assertIn('height', data) self.assertIn('maxheight', data) self.assertTrue(data['type'], 'rich') self.assertTrue(data['version'], '1.0') self.assertIn(territory.title, data['html']) self.assertIn(cgi.escape(territory.url), data['html']) self.assertIn('alt="{name}"'.format(name=organization.name), data['html']) self.assertIn(md(territory.description, source_tooltip=True), data['html']) self.assertIn('Download from localhost', data['html']) self.assertIn('Add to your own website', data['html']) if territory_dataset_class not in ( TERRITORY_DATASETS['region']['comptes_r'], TERRITORY_DATASETS['region']['zonages_r']): self.assertIn( 'License: {title}'.format(title=licence_ouverte.title), data['html']) self.assertIn( '© {license_id}'.format(license_id=licence_ouverte.id), data['html']) self.assertIn( '<a data-tooltip="Source" href="http://localhost/datasets', data['html'])
def test_counties_with_other_datasets_logged_in(self): self.login() with self.autoindex(): organization = OrganizationFactory() for _ in range(3): VisibleDatasetFactory( organization=organization, spatial=SpatialCoverageFactory(zones=[self.bdr.id])) response = self.client.get( url_for('territories.territory', territory=self.bdr)) self.assert200(response) data = response.data.decode('utf-8') base_datasets = self.get_context_variable('base_datasets') self.assertEqual(len(base_datasets), 0) other_datasets = self.get_context_variable('other_datasets') self.assertEqual(len(other_datasets), 3) self.assertFalse(self.get_context_variable('has_pertinent_datasets')) self.assertEqual(self.get_context_variable('territory_datasets'), []) self.assertIn('If you want your datasets to appear in that list', data)
def test_with_organization_object_from_json(self): Ownable, OwnableForm = self.factory() user = UserFactory() member = Member(user=user, role='editor') org = OrganizationFactory(members=[member]) login_user(user) form = OwnableForm.from_json({'organization': {'id': str(org.id)}}) self.assertEqual(form.organization.data, org) form.validate() self.assertEqual(form.errors, {}) ownable = Ownable() form.populate_obj(ownable) self.assertIsNone(ownable.owner) self.assertEqual(ownable.organization, org)
def test_recent_feed_org(self): owner = UserFactory() org = OrganizationFactory() DatasetFactory( owner=owner, organization=org, resources=[ResourceFactory()]) response = self.get(url_for('datasets.recent_feed')) self.assert200(response) feed = feedparser.parse(response.data) self.assertEqual(len(feed.entries), 1) entry = feed.entries[0] self.assertEqual(len(entry.authors), 1) author = entry.authors[0] self.assertEqual(author.name, org.name) self.assertEqual(author.href, self.full_url('organizations.show', org=org.id))
def test_oembed_town_territory_api_get(self): '''It should fetch a town territory in the oembed format.''' paca, bdr, arles = create_geozones_fixtures() licence_ouverte = LicenseFactory(id='fr-lo', title='Licence Ouverte') odbl_license = LicenseFactory(id='odc-odbl', title='ODbL') LicenseFactory(id='notspecified', title='Not Specified') town_datasets = TERRITORY_DATASETS['commune'] for territory_dataset_class in town_datasets.values(): organization = OrganizationFactory( id=territory_dataset_class.organization_id) territory = territory_dataset_class(arles) reference = 'territory-{id}'.format(id=territory.slug) response = self.get(url_for('api.oembeds', references=reference)) self.assert200(response) data = json.loads(response.data)[0] self.assertIn('html', data) self.assertIn('width', data) self.assertIn('maxwidth', data) self.assertIn('height', data) self.assertIn('maxheight', data) self.assertTrue(data['type'], 'rich') self.assertTrue(data['version'], '1.0') self.assertIn(territory.title, data['html']) self.assertIn(cgi.escape(territory.url), data['html']) self.assertIn('alt="{name}"'.format(name=organization.name), data['html']) self.assertIn(md(territory.description, source_tooltip=True), data['html']) self.assertIn('Download from localhost', data['html']) self.assertIn('Add to your own website', data['html']) if territory_dataset_class not in (town_datasets['comptes_com'], ): if territory_dataset_class == town_datasets['ban_odbl_com']: license = odbl_license else: license = licence_ouverte self.assertIn('License: {title}'.format(title=license.title), data['html']) self.assertIn('© {license_id}'.format(license_id=license.id), data['html']) self.assertIn( '<a data-tooltip="Source" href="http://localhost/datasets', data['html'])
def test_issues_for_user_with_org(self): user = UserFactory() member = Member(user=user, role='editor') org = OrganizationFactory(members=[member]) dataset = DatasetFactory(organization=org) reuse = ReuseFactory(organization=org) open_issues = [] for i in range(3): sender = UserFactory() message = Message(content=faker.sentence(), posted_by=sender) open_issues.append(Issue.objects.create( subject=dataset, user=sender, title=faker.sentence(), discussion=[message] )) open_issues.append(Issue.objects.create( subject=reuse, user=sender, title=faker.sentence(), discussion=[message] )) # Creating a closed issue that shouldn't show up in response. other_user = UserFactory() message = Message(content=faker.sentence(), posted_by=other_user) Issue.objects.create( subject=dataset, user=other_user, title=faker.sentence(), discussion=[message], closed=datetime.now(), closed_by=user ) issues = issues_for(user) self.assertIsInstance(issues, db.BaseQuerySet) self.assertEqual(len(issues), len(open_issues)) for issue in issues: self.assertIn(issue, open_issues)
def test_simple_flat(self): filename = 'flat.jsonld' url = mock_dcat(filename) org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() self.assertEqual(len(job.items), 3) datasets = {d.extras['dct:identifier']: d for d in Dataset.objects} self.assertEqual(len(datasets), 3) for i in '1 2 3'.split(): d = datasets[i] self.assertEqual(d.title, 'Dataset {0}'.format(i)) self.assertEqual(d.description, 'Dataset {0} description'.format(i)) self.assertEqual(d.extras['dct:identifier'], i) # First dataset dataset = datasets['1'] self.assertEqual( dataset.tags, ['tag-1', 'tag-2', 'tag-3', 'tag-4', 'theme-1', 'theme-2']) self.assertEqual(len(dataset.resources), 2) # Second dataset dataset = datasets['2'] self.assertEqual(dataset.tags, ['tag-1', 'tag-2', 'tag-3']) self.assertEqual(len(dataset.resources), 2) # Third dataset dataset = datasets['3'] self.assertEqual(dataset.tags, ['tag-1', 'tag-2']) self.assertEqual(len(dataset.resources), 1)
def test_unable_to_detect_format(self): url = DCAT_URL_PATTERN.format(path='', domain=TEST_DOMAIN) httpretty.register_uri(httpretty.HEAD, url, content_type='') org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() self.assertEqual(job.status, 'failed') self.assertEqual(len(job.errors), 1) error = job.errors[0] expected = 'Unable to detect format from extension or mime type' self.assertEqual(error.message, expected)
def test_unable_to_detect_format(self, rmock): url = DCAT_URL_PATTERN.format(path='', domain=TEST_DOMAIN) rmock.head(url, headers={'Content-Type': ''}) org = OrganizationFactory() source = HarvestSourceFactory(backend='dcat', url=url, organization=org) actions.run(source.slug) source.reload() job = source.get_last_job() assert job.status == 'failed' assert len(job.errors) == 1 error = job.errors[0] expected = 'Unable to detect format from extension or mime type' assert error.message == expected
def test_create_with_file(self): '''It should create a resource from the API with a file''' user = self.login() with self.autoindex(): org = OrganizationFactory( members=[Member(user=user, role='admin')]) dataset = DatasetFactory(organization=org) response = self.post(url_for('api.upload_new_dataset_resource', dataset=dataset), {'file': (StringIO(b'aaa'), 'test.txt')}, json=False) self.assert201(response) data = json.loads(response.data) self.assertEqual(data['title'], 'test.txt') response = self.put( url_for('api.resource', dataset=dataset, rid=data['id']), data) self.assert200(response) dataset.reload() self.assertEqual(len(dataset.resources), 1) self.assertTrue(dataset.resources[0].url.endswith('test.txt'))