Skip to content

Commit

Permalink
Merge 06272b6 into 3b9447b
Browse files Browse the repository at this point in the history
  • Loading branch information
lrromero committed Oct 19, 2018
2 parents 3b9447b + 06272b6 commit c141577
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 31 deletions.
9 changes: 9 additions & 0 deletions docs/MANUAL.md
Expand Up @@ -428,6 +428,15 @@ Toma los siguientes parámetros:
portal de destino. Si no se pasa, se toma como organización el catalog_id

Retorna el id en el nodo de destino de los datasets federados.

### Métodos para manejo de organizaciones

- **pydatajson.federation.get_organizations_from_ckan()**: Devuelve el árbol de organizaciones del portal pasado por parámetro.
Toma los siguientes parámetros:
- **portal_url**: URL del portal de CKAN. Debe implementar el endpoint `/group_tree`.

Retorna una lista de diccionarios con la información de las organizaciones. Recursivamente, dentro del campo `children`,
se encuentran las organizaciones dependientes en la jerarquía.

## Anexo I: Estructura de respuestas

Expand Down
14 changes: 14 additions & 0 deletions pydatajson/federation.py
Expand Up @@ -300,3 +300,17 @@ def push_new_themes(catalog, portal_url, apikey):
catalog, portal_url, apikey, identifier=new_theme)
pushed_names.append(name)
return pushed_names


def get_organizations_from_ckan(portal_url):
"""Toma la url de un portal y devuelve su árbol de organizaciones.
Args:
portal_url (str): La URL del portal CKAN de origen.
Returns:
dict: Diccionarios anidados con la información de
las organizaciones.
"""
ckan_portal = RemoteCKAN(portal_url)
return ckan_portal.call_action('group_tree',
data_dict={'type': 'organization'})
50 changes: 19 additions & 31 deletions tests/test_federation.py
Expand Up @@ -18,12 +18,15 @@
SAMPLES_DIR = os.path.join("tests", "samples")


class PushDatasetTestCase(unittest.TestCase):

class FederationSuite(unittest.TestCase):
@classmethod
def get_sample(cls, sample_filename):
return os.path.join(SAMPLES_DIR, sample_filename)


@patch('pydatajson.federation.RemoteCKAN', autospec=True)
class PushDatasetTestCase(FederationSuite):

@classmethod
def setUpClass(cls):
cls.catalog = pydatajson.DataJson(cls.get_sample('full_data.json'))
Expand All @@ -43,7 +46,6 @@ def setUpClass(cls):
cls.minimum_dataset['distribution'][0][
'identifier'] = cls.dataset['distribution'][0]['identifier']

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_id_is_created_correctly(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -62,7 +64,6 @@ def mock_call_action(action, data_dict=None):
catalog_id=self.catalog_id)
self.assertEqual(self.catalog_id + '_' + self.dataset_id, res_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_id_is_updated_correctly(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -81,7 +82,6 @@ def mock_call_action(action, data_dict=None):
catalog_id=self.catalog_id)
self.assertEqual(self.catalog_id + '_' + self.dataset_id, res_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_dataset_id_is_preserved_if_catalog_id_is_not_passed(
self, mock_portal):
def mock_call_action(action, data_dict=None):
Expand All @@ -97,7 +97,6 @@ def mock_call_action(action, data_dict=None):
'portal', 'key')
self.assertEqual(self.dataset_id, res_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_tags_are_passed_correctly(self, mock_portal):
themes = self.dataset['theme']
keywords = [kw for kw in self.dataset['keyword']]
Expand Down Expand Up @@ -132,7 +131,6 @@ def mock_call_action(action, data_dict=None):
catalog_id=self.catalog_id)
self.assertEqual(self.catalog_id + '_' + self.dataset_id, res_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_licenses_are_interpreted_correctly(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'license_list':
Expand All @@ -149,7 +147,6 @@ def mock_call_action(action, data_dict=None):
push_dataset_to_ckan(self.catalog, 'owner', self.dataset_id,
'portal', 'key', catalog_id=self.catalog_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_dataset_without_license_sets_notspecified(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'license_list':
Expand All @@ -172,7 +169,6 @@ def mock_call_action(action, data_dict=None):
'key',
catalog_id=self.minimum_catalog_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_dataset_level_wrappers(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -192,7 +188,6 @@ def mock_call_action(action, data_dict=None):
self.assertEqual(self.dataset_id, restored_id)
self.assertEqual(self.catalog_id + '_' + self.dataset_id, harvested_id)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_harvest_catalog_with_no_optional_parametres(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -218,7 +213,6 @@ def mock_call_action(action, data_dict=None):
for ds in self.catalog.datasets],
harvested_ids)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_harvest_catalog_with_dataset_list(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand Down Expand Up @@ -254,7 +248,6 @@ def mock_call_action(action, data_dict=None):
[self.catalog_id + '_' + ds_id for ds_id in dataset_list],
harvested_ids)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_harvest_catalog_with_owner_org(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -275,7 +268,6 @@ def mock_call_action(action, data_dict=None):
for ds in self.catalog.datasets],
harvested_ids)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_harvest_catalog_with_errors(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'package_update':
Expand All @@ -292,7 +284,6 @@ def mock_call_action(action, data_dict=None):
self.assertDictEqual(
{self.catalog.datasets[1]['identifier']: "some message"}, errors)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_harvest_catalog_with_empty_list(self, mock_portal):
harvested_ids, _ = harvest_catalog_to_ckan(
self.catalog, 'portal', 'key', self.catalog_id,
Expand All @@ -301,7 +292,7 @@ def test_harvest_catalog_with_empty_list(self, mock_portal):
self.assertEqual([], harvested_ids)


class RemoveDatasetTestCase(unittest.TestCase):
class RemoveDatasetTestCase(FederationSuite):

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_empty_search_doesnt_call_purge(self, mock_portal):
Expand Down Expand Up @@ -378,22 +369,17 @@ def test_remove_through_filters_and_organization(
'dataset_purge', data_dict={'id': 'id_2'})


class PushThemeTestCase(unittest.TestCase):

@classmethod
def get_sample(cls, sample_filename):
return os.path.join(SAMPLES_DIR, sample_filename)
@patch('pydatajson.federation.RemoteCKAN', autospec=True)
class PushThemeTestCase(FederationSuite):

@classmethod
def setUpClass(cls):
cls.catalog = pydatajson.DataJson(cls.get_sample('full_data.json'))

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_empty_theme_search_raises_exception(self, mock_portal):
with self.assertRaises(AssertionError):
push_theme_to_ckan(self.catalog, 'portal_url', 'apikey')

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_function_pushes_theme_by_identifier(self, mock_portal):
mock_portal.return_value.call_action = MagicMock(
return_value={'name': 'group_name'})
Expand All @@ -404,7 +390,6 @@ def test_function_pushes_theme_by_identifier(self, mock_portal):
identifier='compras')
self.assertEqual('group_name', result)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_function_pushes_theme_by_label(self, mock_portal):
mock_portal.return_value.call_action = MagicMock(
return_value={'name': 'other_name'})
Expand All @@ -415,7 +400,6 @@ def test_function_pushes_theme_by_label(self, mock_portal):
label='Adjudicaciones')
self.assertEqual('other_name', result)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_ckan_portal_is_called_with_correct_parametres(self, mock_portal):
mock_portal.return_value.call_action = MagicMock(
return_value={'name': u'contrataciones'})
Expand All @@ -431,16 +415,13 @@ def test_ckan_portal_is_called_with_correct_parametres(self, mock_portal):
'group_create', data_dict=group)


class PushCatalogThemesTestCase(unittest.TestCase):
@classmethod
def get_sample(cls, sample_filename):
return os.path.join(SAMPLES_DIR, sample_filename)
@patch('pydatajson.federation.RemoteCKAN', autospec=True)
class PushCatalogThemesTestCase(FederationSuite):

@classmethod
def setUpClass(cls):
cls.catalog = pydatajson.DataJson(cls.get_sample('full_data.json'))

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_empty_portal_pushes_every_theme(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'group_list':
Expand All @@ -461,7 +442,6 @@ def mock_call_action(action, data_dict=None):
[theme['id'] for theme in self.catalog['themeTaxonomy']],
res_names)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_full_portal_pushes_nothing(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'group_list':
Expand All @@ -476,7 +456,6 @@ def mock_call_action(action, data_dict=None):
except AttributeError:
self.assertCountEqual([], res_names)

@patch('pydatajson.federation.RemoteCKAN', autospec=True)
def test_non_empty_intersection_pushes_missing_themes(self, mock_portal):
def mock_call_action(action, data_dict=None):
if action == 'group_list':
Expand All @@ -497,3 +476,12 @@ def mock_call_action(action, data_dict=None):
self.assertCountEqual(
[theme['id'] for theme in self.catalog['themeTaxonomy']][2:],
res_names)


@patch('pydatajson.federation.RemoteCKAN', autospec=True)
class OrganizationsTestCase(FederationSuite):

def test_get_organization_calls_api_correctly(self, mock_portal):
get_organizations_from_ckan('portal_url')
mock_portal.return_value.call_action.assert_called_with(
'group_tree', data_dict={'type': 'organization'})

0 comments on commit c141577

Please sign in to comment.