""" ARCHES - a program developed to inventory and manage immovable cultural heritage. Copyright (C) 2013 J. Paul Getty Trust and World Monuments Fund This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . """ import os import json import csv from django.test.utils import captured_stdout from arches.app.utils.data_management.resources.formats.csvfile import ( CsvWriter, MissingConfigException, ) from operator import itemgetter from tests.base_test import ArchesTestCase from arches.app.utils.skos import SKOSReader from arches.app.utils.betterJSONSerializer import JSONDeserializer from arches.app.utils.data_management.resources.importer import BusinessDataImporter from arches.app.utils.data_management.resources.exporter import ( ResourceExporter as BusinessDataExporter, ) from arches.app.utils.data_management.resource_graphs.importer import ( import_graph as ResourceGraphImporter, ) # these tests can be run from the command line via # python manage.py test tests.exporter.resource_export_tests --settings="tests.test_settings" class BusinessDataExportTests(ArchesTestCase): @classmethod def setUpTestData(cls): super().setUpTestData() skos = SKOSReader() rdf = skos.read_file("tests/fixtures/data/concept_label_test_scheme.xml") ret = skos.save_concepts_from_skos(rdf) skos = SKOSReader() rdf = skos.read_file("tests/fixtures/data/concept_label_test_collection.xml") ret = skos.save_concepts_from_skos(rdf) with open( os.path.join("tests/fixtures/resource_graphs/resource_export_test.json"), "r", ) as f: archesfile = JSONDeserializer().deserialize(f) ResourceGraphImporter(archesfile["graph"]) def test_invalid_writer_config(self): with self.assertRaises(MissingConfigException): CsvWriter() def test_csv_export(self): with captured_stdout(): BusinessDataImporter( "tests/fixtures/data/csv/resource_export_test.csv" ).import_business_data() export = BusinessDataExporter( "csv", configs="tests/fixtures/data/csv/resource_export_test.mapping", single_file=True, ).export(languages="en") csv_output = list( csv.DictReader(export[0]["outputfile"].getvalue().split("\r\n")) )[0] csvinputfile = "tests/fixtures/data/csv/resource_export_test.csv" with open(csvinputfile, "r", encoding="utf-8") as f: csv_input = list( csv.DictReader( f, restkey="ADDITIONAL", restval="MISSING", ) )[0] self.assertDictEqual(dict(csv_input), dict(csv_output)) def test_json_export(self): def deep_sort(obj): """ Recursively sort list or dict nested lists. Taken from https://stackoverflow.com/questions/18464095/how-to-achieve-assertdictequal-with-assertsequenceequal-applied-to-values """ if isinstance(obj, dict): _sorted = {} for key in sorted(obj): _sorted[key] = deep_sort(obj[key]) elif isinstance(obj, list): new_list = [] for val in obj: new_list.append(deep_sort(val)) if all( isinstance(item, dict) and "resourceinstance" in item for item in new_list ): _sorted = sorted( new_list, key=lambda item: item["resourceinstance"]["resourceinstanceid"], ) else: try: _sorted = sorted(new_list, key=itemgetter("tileid")) except: _sorted = new_list else: _sorted = obj return _sorted with captured_stdout(): BusinessDataImporter( "tests/fixtures/data/json/resource_export_business_data_truth.json" ).import_business_data() export = BusinessDataExporter("json").export( "ab74af76-fa0e-11e6-9e3e-026d961c88e6" ) json_export = deep_sort(json.loads(export[0]["outputfile"].getvalue())) with open( "tests/fixtures/data/json/resource_export_business_data_truth.json" ) as f: json_truth = deep_sort(json.load(f)) self.maxDiff = None # removes dynamic value "createdtime" from export to compare with static truth value for resource in json_export["business_data"]["resources"]: instance = resource["resourceinstance"] if "createdtime" in instance: del instance["createdtime"] self.assertDictEqual(json_export, json_truth)