diff --git a/.circleci/config.yml b/.circleci/config.yml index 311943563..d4db0d017 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,22 +1,39 @@ -version: 2 +version: 2.1 machine: environment: - DJANGO_SETTINGS_MODULE: repair.settings4tests + DJANGO_SETTINGS_MODULE: repair.settings_circleci jobs: django testing: docker: - - image: maxboh/docker-circleci-node-miniconda-gdal:graph_tool_stretch + - image: gertzgutscheruemenapp/repair-web + - image: circleci/postgres:13-postgis-ram + environment: + POSTGRES_USER: postgres + POSTGRES_DB: circle_test + POSTGRES_PASSWORD: postgres steps: - checkout - run: mkdir test-reports + - run: source activate repair - run: name: Install Python deps in a venv command: | pip install -r requirements-dev.txt + - run: + name: Install dockerize + command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz + environment: + DOCKERIZE_VERSION: v0.6.1 + - run: + name: Wait for Router + command: dockerize -wait tcp://localhost:8001 -timeout 1m + - run: + name: Wait for Database + command: dockerize -wait tcp://localhost:5432 -timeout 1m - run: name: Migrate Test Database command: | - python manage.py migrate --settings=repair.settings4tests + python manage.py migrate --settings=datentool.settings_circleci - store_artifacts: path: test-reports/ destination: tr1 @@ -25,13 +42,13 @@ jobs: - run: name: codecov command: | - coverage run manage.py test --settings=repair.settings4tests + coverage run manage.py test --settings=repair.settings_circleci codecov selenium testing: docker: - - image: maxboh/docker-circleci-node-miniconda-gdal:graph_tool_stretch + - image: gertzgutscheruemenapp/repair-web steps: - checkout - run: @@ -72,28 +89,9 @@ jobs: path: repair/tests/artifacts - setup database: - docker: - - image: maxboh/docker-circleci-node-miniconda-gdal:graph_tool_stretch - steps: - - checkout - - run: - name: Install Python deps in a venv - command: | - pip install -r requirements-dev.txt - - run: - name: Migrate Test Database again - command: | - python manage.py migrate --run-syncdb --settings=repair.settings4tests - - run: - name: load fixtures to test database - command: | - python manage.py loaddata sandbox_data --settings=repair.settings4tests - - jasmine tests: docker: - - image: maxboh/docker-circleci-node-miniconda-gdal:graph_tool_stretch + - image: gertzgutscheruemenapp/repair-web steps: - checkout - run: mkdir test-reports @@ -129,4 +127,3 @@ workflows: build-and-deploy: jobs: - django testing - - setup database diff --git a/Dockerfile b/Dockerfile index fa394380e..e805aa2b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,35 @@ -FROM maxboh/docker-circleci-node-miniconda-gdal:graph_tool_stretch +FROM osgeo/gdal:ubuntu-small-latest +RUN curl -sL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh +RUN bash nodesource_setup.sh +RUN apt-get -y update \ + && apt-get -y upgrade \ + && apt-get -y install git \ + && apt-get -y install nodejs \ + && apt-get -y install python3-pip \ + && apt-get -y install libpq-dev \ + && apt-get -y install binutils libproj-dev libgeos-dev \ + && apt-get -y install osmium-tool \ + && apt-get -y install language-pack-de wget \ + && apt-get -y install libxcursor1 libgtk-3-0 \ + && apt-get install -y libpq-dev \ + && apt-get install -y gettext imagemagick ghostscript + +RUN npm install --global yarn + +RUN mkdir /miniconda3 +RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /miniconda3/miniconda.sh +RUN bash /miniconda3/miniconda.sh -b -u -p /miniconda3 +RUN /miniconda3/bin/conda create -n repair -c conda-forge graph-tool gdal python=3.10 + +RUN git clone https://github.com/MaxBo/REPAiR-Web.git /repairweb +WORKDIR /repairweb +RUN git pull +RUN git checkout feature/update + +ENV PATH="${PATH}:/miniconda3/bin" +SHELL ["conda", "run", "-n", "repair", "/bin/bash", "-c"] + +RUN python -m pip install pip==22 +RUN pip install -r /repairweb/requirements.txt -RUN git clone https://github.com/MaxBo/REPAiR-Web.git $HOME/repairweb -RUN cd $HOME/repairweb diff --git a/repair/.gitignore b/repair/.gitignore index 9e02c9b69..8bd082fe0 100644 --- a/repair/.gitignore +++ b/repair/.gitignore @@ -5,3 +5,4 @@ static/bundles !static/data/*.json /settings_dev_local_pg.py /settings_tests_local_pg.py +/settings_local.py diff --git a/repair/apps/asmfa/apps.py b/repair/apps/asmfa/apps.py deleted file mode 100644 index 57706b635..000000000 --- a/repair/apps/asmfa/apps.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.apps import AppConfig - - -class AsmfaConfig(AppConfig): - name = 'asmfa' diff --git a/repair/apps/asmfa/graphs/graph.py b/repair/apps/asmfa/graphs/graph.py index e4dd6bbc6..4503def0b 100644 --- a/repair/apps/asmfa/graphs/graph.py +++ b/repair/apps/asmfa/graphs/graph.py @@ -1,10 +1,11 @@ +graph_tools_failed = False try: import graph_tool as gt from graph_tool import stats as gt_stats from graph_tool import draw, util import cairo except ModuleNotFoundError: - pass + graph_tools_failed = True from django.db.models import Q, Sum, F from django.db.models.functions import Coalesce diff --git a/repair/apps/asmfa/serializers/locations.py b/repair/apps/asmfa/serializers/locations.py index 1c5a46111..98c4a7a07 100644 --- a/repair/apps/asmfa/serializers/locations.py +++ b/repair/apps/asmfa/serializers/locations.py @@ -34,7 +34,7 @@ class AdministrativeLocationSerializer(PatchFields, 'actor__activity__activitygroup__keyflow__casestudy__id', 'keyflow_pk': 'actor__activity__activitygroup__keyflow__id', } - actor = ActorIDField() + actor = ActorIDField(required=False) area = serializers.PrimaryKeyRelatedField(required=False, allow_null=True, queryset=Area.objects.all()) level = serializers.PrimaryKeyRelatedField( diff --git a/repair/apps/asmfa/tests/data/T3.2_Activities.tsv b/repair/apps/asmfa/tests/data/T3.2_Activities.tsv index f86eb9c7a..877459266 100644 --- a/repair/apps/asmfa/tests/data/T3.2_Activities.tsv +++ b/repair/apps/asmfa/tests/data/T3.2_Activities.tsv @@ -8,7 +8,7 @@ F-4391 F-4391 Roofing activities F F-4222 F-4222 Construction of utility projects for electricity and telecommunications F F-4291 F-4291 Construction of water projects F F-4299 F-4299 Construction of other civil engineering projects n.e.c. F -F-4212 F-4212 Construction of railways and underground railwaysÊ F +F-4212 F-4212 Construction of railways and underground railways F F-4333 F-4333 Floor and wall covering F F-4329 F-4329 Other construction installation F F-4332 F-4332 Joinery installation F diff --git a/repair/apps/asmfa/tests/test_activitygroup.py b/repair/apps/asmfa/tests/test_activitygroup.py index 1cf2cfda9..9d7fe395e 100644 --- a/repair/apps/asmfa/tests/test_activitygroup.py +++ b/repair/apps/asmfa/tests/test_activitygroup.py @@ -24,20 +24,21 @@ def setUpClass(cls): keyflow_pk=cls.keyflow) cls.url_pk = dict(pk=cls.activitygroup) - def setUp(self): - super().setUp() - self.activitygroup1 = ActivityGroupFactory(name='MyGroup', - keyflow=self.kic) - self.activitygroup2 = ActivityGroupFactory(name='AnotherGroup', - keyflow=self.kic) - self.activity1 = ActivityFactory(nace='NACE1', - activitygroup=self.activitygroup1) - self.activity2 = ActivityFactory(nace='NACE2', - activitygroup=self.activitygroup1) - self.activity3 = ActivityFactory(nace='NACE3', - activitygroup=self.activitygroup1) - self.activity4 = ActivityFactory(nace='NACE4', - activitygroup=self.activitygroup2) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.activitygroup1 = ActivityGroupFactory(name='MyGroup', + keyflow=cls.kic_obj) + cls.activitygroup2 = ActivityGroupFactory(name='AnotherGroup', + keyflow=cls.kic_obj) + cls.activity1 = ActivityFactory(nace='NACE1', + activitygroup=cls.activitygroup1) + cls.activity2 = ActivityFactory(nace='NACE2', + activitygroup=cls.activitygroup1) + cls.activity3 = ActivityFactory(nace='NACE3', + activitygroup=cls.activitygroup1) + cls.activity4 = ActivityFactory(nace='NACE4', + activitygroup=cls.activitygroup2) def test_nace_codes(self): """ diff --git a/repair/apps/asmfa/tests/test_actors.py b/repair/apps/asmfa/tests/test_actors.py index b98dbc57a..434e5d595 100644 --- a/repair/apps/asmfa/tests/test_actors.py +++ b/repair/apps/asmfa/tests/test_actors.py @@ -62,24 +62,26 @@ def setUpClass(cls): year=2017, turnover='1000.00', employees=2, - activity=1, + activity=cls.activity_obj.id, BvDid='141234', reason=cls.reason1_id) cls.put_data = dict(name='posttestname', year=2017, turnover='1000.00', employees=2, - activity=1, + activity=cls.activity_obj.id, BvDid='141234', reason=cls.reason2_id) cls.patch_data = dict(name='patchtestname') - def setUp(self): - super().setUp() - self.reason1 = ReasonFactory(id=self.reason1_id, reason='Reason 1') - self.reason2 = ReasonFactory(id=self.reason2_id, reason='Reason 2') - self.obj = ActorFactory(activity__activitygroup__keyflow=self.kic, - reason=self.reason1) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.reason1 = ReasonFactory(id=cls.reason1_id, reason='Reason 1') + cls.reason2 = ReasonFactory(id=cls.reason2_id, reason='Reason 2') + cls.activity_obj = ActivityFactory(activitygroup__keyflow=cls.kic_obj) + cls.obj = ActorFactory(activity=cls.activity_obj, + reason=cls.reason1) def test_reason(self): """Test reason for exclusion""" @@ -142,12 +144,12 @@ def setUpClass(cls): activitygroup=cls.activitygroup) cls.patch_data = dict(name='Test Name') - def setUp(self): - super().setUp() - self.obj = ActivityFactory( - activitygroup__keyflow__casestudy=self.uic.casestudy, - activitygroup__keyflow=self.kic, - activitygroup__id=self.activitygroup) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = ActivityFactory( + activitygroup__keyflow=cls.kic_obj, + activitygroup__id=cls.activitygroup) def test_unique_nacecode(self): """Test if the nace-code number is unique""" @@ -188,6 +190,7 @@ def setUpClass(cls): cls.put_data = dict(code="P1", name='Test Code') cls.patch_data = dict(name='P1') - def setUp(self): - super().setUp() - self.obj = ActivityGroupFactory(keyflow=self.kic) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = ActivityGroupFactory(keyflow=cls.kic_obj) diff --git a/repair/apps/asmfa/tests/test_bulk.py b/repair/apps/asmfa/tests/test_bulk.py index 3d14cd09d..e6b9d7516 100644 --- a/repair/apps/asmfa/tests/test_bulk.py +++ b/repair/apps/asmfa/tests/test_bulk.py @@ -14,16 +14,14 @@ from repair.apps.asmfa.factories import (ActivityFactory, ActivityGroupFactory, ActorFactory, - UserInCasestudyFactory, KeyflowInCasestudyFactory, CompositionFactory, Actor2ActorFactory, MaterialFactory, ProductFractionFactory, - KeyflowFactory ) -from repair.apps.asmfa.models import (ActivityGroup, Activity, Actor, +from repair.apps.asmfa.models import (ActivityGroup, Activity, Material, ProductFraction, AdministrativeLocation, Actor2Actor, FractionFlow) @@ -50,34 +48,32 @@ class BulkImportNodesTest(LoginTestCase, APITestCase): def setUpClass(cls): super().setUpClass() - cls.keyflow = cls.kic - cls.casestudy = cls.uic.casestudy - cls.ag_url = reverse('activitygroup-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.ac_url = reverse('activity-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.actor_url = reverse('actor-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.location_url = reverse('administrativelocation-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) - def setUp(self): - super().setUp() + @classmethod + def setUpTestData(cls): + super().setUpTestData() # create another activitygroup - ag_f = ActivityGroupFactory(keyflow=self.keyflow, + ag_f = ActivityGroupFactory(keyflow=cls.kic_obj, name='Construction', code='F') - ActivityGroupFactory(keyflow=self.keyflow, + ActivityGroupFactory(keyflow=cls.kic_obj, name='Some stuff, no idea', code='G') - ActivityGroupFactory(keyflow=self.keyflow, + ActivityGroupFactory(keyflow=cls.kic_obj, name='Other', code='E') - ActivityGroupFactory(keyflow=self.keyflow, + ActivityGroupFactory(keyflow=cls.kic_obj, name='Export', code='WE') - ActivityGroupFactory(keyflow=self.keyflow, + ActivityGroupFactory(keyflow=cls.kic_obj, name='Import', code='R') af = ActivityFactory(activitygroup=ag_f, name='should_be_updated', @@ -110,7 +106,7 @@ def test_bulk_group(self): 'bulk_upload' : open(file_path_ag, 'rb'), } - existing_ags = ActivityGroup.objects.filter(keyflow=self.kic) + existing_ags = ActivityGroup.objects.filter(keyflow=self.kic_obj) existing_codes = list(existing_ags.values_list('code', flat=True)) encoding = 'utf8' @@ -127,12 +123,12 @@ def test_bulk_group(self): assert len(res_json['created']) == len(new_codes) # assert that the number of activities matches - all_ag = ActivityGroup.objects.filter(keyflow_id=self.kic.id) + all_ag = ActivityGroup.objects.filter(keyflow_id=self.kic_obj.id) assert len(all_ag) == len(existing_codes) + len(new_codes) # assert that the Name matches in all values for row in df_file_ags.itertuples(index=False): - ag = ActivityGroup.objects.get(keyflow=self.keyflow, + ag = ActivityGroup.objects.get(keyflow=self.kic_obj, code=row.code) assert ag.name == row.name @@ -178,7 +174,7 @@ def test_bulk_activity(self): 'bulk_upload' : open(file_path_ac, 'rb'), } - existing_acs = Activity.objects.filter(activitygroup__keyflow=self.kic) + existing_acs = Activity.objects.filter(activitygroup__keyflow=self.kic_obj) existing_nace = list(existing_acs.values_list('nace', flat=True)) encoding = 'cp1252' @@ -195,7 +191,7 @@ def test_bulk_activity(self): assert len(res_json['created']) == len(new_nace) # assert that the number of activities matches - all_ac = Activity.objects.filter(activitygroup__keyflow=self.kic) + all_ac = Activity.objects.filter(activitygroup__keyflow=self.kic_obj) assert len(all_ac) == len(existing_nace) + len(new_nace) # assert that the Name matches in all values @@ -304,24 +300,22 @@ class BulkImportFlowsTest(LoginTestCase, APITestCase): def setUpClass(cls): super().setUpClass() - cls.keyflow = cls.kic - cls.casestudy = cls.uic.casestudy - cls.a2a_url = reverse('actor2actor-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.astock_url = reverse('actorstock-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) # workaround, don't want to tests any permissions here #cls.uic.user.user.is_superuser = True #cls.uic.user.user.save() - def setUp(self): - super().setUp() + @classmethod + def setUpTestData(cls): + super().setUpTestData() # create another activitygroup - ag = ActivityGroupFactory(keyflow=self.keyflow, name='A', code='A') + ag = ActivityGroupFactory(keyflow=cls.kic_obj, name='A', code='A') af = ActivityFactory(activitygroup=ag, name='B', nace='123') ac_1 = ActorFactory(activity=af, BvDid='WK036306') @@ -330,20 +324,20 @@ def setUp(self): ActorFactory(activity=af, BvDid='WK036309') ac_3 = ActorFactory(activity=af, BvDid='NL59307803') - self.composition = CompositionFactory(name='RES @Urbanisation lvl 1') + cls.composition = CompositionFactory(name='RES @Urbanisation lvl 1') mat1 = MaterialFactory() mat2 = MaterialFactory() - ProductFractionFactory(composition=self.composition, material=mat1, + ProductFractionFactory(composition=cls.composition, material=mat1, publication=None) - ProductFractionFactory(composition=self.composition, material=mat2, + ProductFractionFactory(composition=cls.composition, material=mat2, publication=None) a = PublicationFactory(citekey='cbs2018', title='sth') - PublicationInCasestudyFactory(casestudy=self.casestudy, + PublicationInCasestudyFactory(casestudy=cls.casestudy_obj, publication=a) - Actor2ActorFactory(origin=ac_1, destination=ac_2, keyflow=self.keyflow) - Actor2ActorFactory(origin=ac_1, destination=ac_3, keyflow=self.keyflow) + Actor2ActorFactory(origin=ac_1, destination=ac_2, keyflow=cls.kic_obj) + Actor2ActorFactory(origin=ac_1, destination=ac_3, keyflow=cls.kic_obj) def test_bulk_flow(self): """Test file-based upload of actor2actor""" @@ -415,37 +409,35 @@ class BulkImportMaterialsTest(LoginTestCase, APITestCase): def setUpClass(cls): super().setUpClass() - cls.keyflow = cls.kic - cls.casestudy = cls.uic.casestudy - cls.mat_url = reverse('material-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.waste_url = reverse('waste-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) cls.product_url = reverse('product-list', - kwargs={'casestudy_pk': cls.casestudy.id, - 'keyflow_pk': cls.keyflow.id}) + kwargs={'casestudy_pk': cls.casestudy_obj.id, + 'keyflow_pk': cls.kic_obj.id}) - def setUp(self): - super().setUp() + @classmethod + def setUpTestData(cls): + super().setUpTestData() # create another keyflow keyflow2 = KeyflowInCasestudyFactory(keyflow__name='concurring') # create mats with same names, should not be picked while bulk creating MaterialFactory(name='a', keyflow=keyflow2) MaterialFactory(name='b', keyflow=keyflow2) - MaterialFactory(name='Mat 1', keyflow=self.keyflow) + MaterialFactory(name='Mat 1', keyflow=cls.kic_obj) # this one is a 'default' material without keyflow and duplicate # to one in the file, the keyflow related one should be preferred - MaterialFactory(name='a', keyflow=self.keyflow) + MaterialFactory(name='a', keyflow=cls.kic_obj) MaterialFactory(name='b') a = PublicationFactory(citekey='crem2017', title='sth') - PublicationInCasestudyFactory(casestudy=self.casestudy, + PublicationInCasestudyFactory(casestudy=cls.casestudy_obj, publication=a) def test_bulk_materials(self): @@ -505,7 +497,7 @@ def test_bulk_products(self): # (common mats) or the keyflow set to this test (set in url as well) for f in fractions: mat = f.material - assert mat.keyflow == None or mat.keyflow.id == self.keyflow.id + assert mat.keyflow == None or mat.keyflow.id == self.kic_obj.id avoidable = fractions.values_list('avoidable', flat=True) # avoidable is set (just checking that not everything is diff --git a/repair/apps/asmfa/tests/test_flows.py b/repair/apps/asmfa/tests/test_flows.py index 0befd7d2c..30e88b677 100644 --- a/repair/apps/asmfa/tests/test_flows.py +++ b/repair/apps/asmfa/tests/test_flows.py @@ -435,9 +435,9 @@ class StrategyFractionFlowTest(TestCase): actor1id = 12 actor2id = 20 actor3id = 30 - flowid1 = 1 - flowid2 = 2 - flowid3 = 3 + flowid1 = 4 + flowid2 = 5 + flowid3 = 6 new_amount1 = 2.0 new_amount2 = 4.0 @@ -445,71 +445,84 @@ class StrategyFractionFlowTest(TestCase): def setUpClass(cls): super().setUpClass() - def setUp(self): - super().setUp() - self.casestudy = CaseStudyFactory(name=self.csname) - self.kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.casestudy, - keyflow__id=self.keyflow_id) - self.activitygroup1 = ActivityGroupFactory(keyflow=self.kic_obj) - self.activity1 = ActivityFactory(activitygroup=self.activitygroup1) - self.actor1 = ActorFactory(id=self.actor1id, activity=self.activity1) - self.activitygroup2 = ActivityGroupFactory(keyflow=self.kic_obj) - self.activity2 = ActivityFactory(activitygroup=self.activitygroup2) - self.actor2 = ActorFactory(id=self.actor2id, activity=self.activity2) - self.activitygroup3 = ActivityGroupFactory(keyflow=self.kic_obj) - self.activity3 = ActivityFactory(activitygroup=self.activitygroup3) - self.actor3 = ActorFactory(id=self.actor3id, activity=self.activity3) - - self.comp1 = CompositionFactory(name='composition1', + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.casestudy = CaseStudyFactory(name=cls.csname) + cls.kic_obj = KeyflowInCasestudyFactory(id=cls.keyflowincasestudy, + casestudy=cls.casestudy, + keyflow__id=cls.keyflow_id) + cls.activitygroup1 = ActivityGroupFactory(keyflow=cls.kic_obj) + cls.activity1 = ActivityFactory(activitygroup=cls.activitygroup1) + cls.actor1 = ActorFactory(id=cls.actor1id, activity=cls.activity1) + cls.activitygroup2 = ActivityGroupFactory(keyflow=cls.kic_obj) + cls.activity2 = ActivityFactory(activitygroup=cls.activitygroup2) + cls.actor2 = ActorFactory(id=cls.actor2id, activity=cls.activity2) + cls.activitygroup3 = ActivityGroupFactory(keyflow=cls.kic_obj) + cls.activity3 = ActivityFactory(activitygroup=cls.activitygroup3) + cls.actor3 = ActorFactory(id=cls.actor3id, activity=cls.activity3) + + cls.comp1 = CompositionFactory(name='composition1', nace='nace1') - self.comp2 = CompositionFactory(name='composition2', + cls.comp2 = CompositionFactory(name='composition2', nace='nace2') - self.mat_obj_1 = MaterialFactory(id=self.material_1, - keyflow=self.kic_obj, + cls.mat_obj_1 = MaterialFactory(id=cls.material_1, + keyflow=cls.kic_obj, parent=None) - self.mat_obj_2 = MaterialFactory(id=self.material_2, - keyflow=self.kic_obj, - parent=self.mat_obj_1) - self.publicationic = PublicationInCasestudyFactory() + cls.mat_obj_2 = MaterialFactory(id=cls.material_2, + keyflow=cls.kic_obj, + parent=cls.mat_obj_1) + cls.publicationic = PublicationInCasestudyFactory() + cls.flow1 = Actor2ActorFactory(id=cls.flowid1, + keyflow=cls.kic_obj, + origin=cls.actor1, + destination=cls.actor2) + cls.flow2 = Actor2ActorFactory(id=cls.flowid2, + keyflow=cls.kic_obj, + origin=cls.actor2, + destination=cls.actor3) + cls.flow3 = Actor2ActorFactory(id=cls.flowid3, + keyflow=cls.kic_obj, + origin=cls.actor2, + destination=cls.actor3) # flow attributes - #self.process = ProcessFactory(name='test-process') - - self.fractionflow1 = FractionFlowFactory(flow_id=self.flowid1, - #process=self.process, - stock=None, - to_stock=False, - origin=self.actor1, - destination=self.actor2, - material=self.mat_obj_1, - nace=self.comp1.nace, - composition_name=self.comp1.name, - publication=self.publicationic, - keyflow=self.kic_obj, - amount=1.0) - self.fractionflow2 = FractionFlowFactory(flow_id=self.flowid2, - stock=None, - to_stock=False, - origin=self.actor2, - destination=self.actor3, - material=self.mat_obj_2, - nace=self.comp1.nace, - composition_name=self.comp1.name, - publication=self.publicationic, - keyflow=self.kic_obj, - amount=1.0) - self.fractionflow3 = FractionFlowFactory(flow_id=self.flowid3, - stock=None, - to_stock=False, - origin=self.actor2, - destination=self.actor3, - material=self.mat_obj_1, - nace=self.comp2.nace, - composition_name=self.comp2.name, - publication=self.publicationic, - keyflow=self.kic_obj, - amount=1.0) + #cls.process = ProcessFactory(name='test-process') + + cls.fractionflow1 = FractionFlowFactory(flow=cls.flow1, + #process=cls.process, + stock=None, + to_stock=False, + origin=cls.actor1, + destination=cls.actor2, + material=cls.mat_obj_1, + nace=cls.comp1.nace, + composition_name=cls.comp1.name, + publication=cls.publicationic, + keyflow=cls.kic_obj, + amount=1.0) + cls.fractionflow2 = FractionFlowFactory(flow=cls.flow2, + stock=None, + to_stock=False, + origin=cls.actor2, + destination=cls.actor3, + material=cls.mat_obj_2, + nace=cls.comp1.nace, + composition_name=cls.comp1.name, + publication=cls.publicationic, + keyflow=cls.kic_obj, + amount=1.0) + cls.fractionflow3 = FractionFlowFactory(flow=cls.flow3, + stock=None, + to_stock=False, + origin=cls.actor2, + destination=cls.actor3, + material=cls.mat_obj_1, + nace=cls.comp2.nace, + composition_name=cls.comp2.name, + publication=cls.publicationic, + keyflow=cls.kic_obj, + amount=1.0) def test_strategyfractionflows(self): diff --git a/repair/apps/asmfa/tests/test_graph.py b/repair/apps/asmfa/tests/test_graph.py index f83e29c22..86195a504 100644 --- a/repair/apps/asmfa/tests/test_graph.py +++ b/repair/apps/asmfa/tests/test_graph.py @@ -1,25 +1,19 @@ import os from test_plus import APITestCase -from django.contrib.gis.geos import Polygon, Point, GeometryCollection +from django.contrib.gis.geos import Polygon from django.db.models.functions import Coalesce -from django.db.models import Case, When, Value, F +from django.db.models import Case, When, F from django.contrib.gis.geos import Polygon, MultiPolygon from django.db.models import Sum from django.test import TestCase -from repair.apps.asmfa.graphs.graph import BaseGraph, StrategyGraph +from repair.apps.asmfa.graphs.graph import (BaseGraph, StrategyGraph, + graph_tools_failed) from repair.apps.asmfa.graphs.graphwalker import GraphWalker -from repair.tests.test import LoginTestCase, AdminAreaTest -from repair.apps.asmfa.factories import (ActorFactory, - ActivityFactory, - ActivityGroupFactory, - MaterialFactory, - FractionFlowFactory, - AdministrativeLocationFactory - ) -from repair.apps.changes.factories import (StrategyFactory, - SolutionInStrategyFactory, - SolutionCategoryFactory, +from repair.tests.test import LoginTestCase +from repair.apps.asmfa.factories import (ActivityFactory, + ActivityGroupFactory) +from repair.apps.changes.factories import (SolutionInStrategyFactory, SolutionFactory, SolutionPartFactory, ImplementationQuestionFactory, @@ -28,18 +22,13 @@ FlowReferenceFactory, ImplementationQuestionFactory, ImplementationQuantityFactory, - KeyflowInCasestudyFactory, PossibleImplementationAreaFactory ) from repair.apps.asmfa.models import (Actor, FractionFlow, StrategyFractionFlow, Activity, Material, KeyflowInCasestudy, CaseStudy, Process) -from repair.apps.changes.models import (Solution, Strategy, - ImplementationQuantity, - SolutionInStrategy, Scheme, +from repair.apps.changes.models import (Scheme, ImplementationArea) -from repair.apps.studyarea.factories import StakeholderFactory -from repair.apps.login.factories import UserInCasestudyFactory from repair.apps.changes.tests.test_graphwalker import MultiplyTestDataMixin from repair.apps.asmfa.tests import flowmodeltestdata @@ -47,6 +36,11 @@ class GraphWalkerTest(TestCase): + def setUp(self): + super().setUp() + if graph_tools_failed: + self.skipTest('no graph tools') + def test_data_creation(self): b2b = flowmodeltestdata.bread_to_beer_graph() assert b2b.num_vertices() == 6 @@ -249,6 +243,8 @@ def setUpClass(cls): def setUp(self): super().setUp() + if graph_tools_failed: + self.skipTest('no graph tools') self.activitygroup1 = ActivityGroupFactory(name='MyGroup', keyflow=self.kic) self.activitygroup2 = ActivityGroupFactory(name='AnotherGroup', @@ -287,9 +283,10 @@ def setUpClass(cls): cls.keyflow = KeyflowInCasestudy.objects.get( casestudy=cls.casestudy, keyflow__name='Food Waste') - cls.basegraph = BaseGraph(cls.keyflow, tag='unittest') - print('building basegraph') - cls.basegraph.build() + if not graph_tools_failed: + cls.basegraph = BaseGraph(cls.keyflow, tag='unittest') + print('building basegraph') + cls.basegraph.build() cls.households = Activity.objects.get(nace='V-0000') cls.collection = Activity.objects.get(nace='E-3811') @@ -299,6 +296,8 @@ def setUpClass(cls): def setUp(self): super().setUp() + if graph_tools_failed: + self.skipTest('no graph tools') self.solution = SolutionFactory(solution_category__keyflow=self.keyflow) self.possible_impl_area = PossibleImplementationAreaFactory( @@ -812,13 +811,13 @@ class PeelPioneerTest(LoginTestCase, APITestCase): @classmethod def setUpClass(cls): super().setUpClass() - cls.casestudy = CaseStudy.objects.get(name='SandboxCity') cls.keyflow = KeyflowInCasestudy.objects.get( casestudy=cls.casestudy, keyflow__name='Food Waste') - cls.basegraph = BaseGraph(cls.keyflow, tag='unittest') - cls.basegraph.build() + if not graph_tools_failed: + cls.basegraph = BaseGraph(cls.keyflow, tag='unittest') + cls.basegraph.build() cls.restaurants = Activity.objects.get(nace='I-5610') cls.retail_food = Activity.objects.get(nace='G-4711') @@ -843,6 +842,8 @@ def setUpClass(cls): def setUp(self): super().setUp() + if graph_tools_failed: + self.skipTest('no graph tools') self.solution = SolutionFactory(solution_category__keyflow=self.keyflow) # create the implementation along with the strategy diff --git a/repair/apps/asmfa/tests/test_keyflows.py b/repair/apps/asmfa/tests/test_keyflows.py index 7fb6af280..d70ada7a4 100644 --- a/repair/apps/asmfa/tests/test_keyflows.py +++ b/repair/apps/asmfa/tests/test_keyflows.py @@ -33,8 +33,9 @@ def setUpClass(cls): code='Food') cls.patch_data = dict(name='patchtestname') - def setUp(self): - super().setUp() + @classmethod + def setUpTestData(self): + super().setUpTestData() self.obj = KeyflowFactory() @@ -63,18 +64,14 @@ def setUpClass(cls): cls.url_pk = dict(pk=cls.keyflow) cls.put_data = dict(note='new_put_note', - keyflow=cls.keyflow, + keyflow=cls.kic_obj.keyflow_id, ) cls.post_data = dict(note='new_note', - keyflow=cls.keyflow, + keyflow=cls.kic_obj.keyflow_id, ) cls.patch_data = dict(note='patchtestnote') - - def setUp(self): - super().setUp() - self.obj = KeyflowInCasestudyFactory(casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) + cls.obj = cls.kic_obj def test_post(self): url = reverse(self.url_key + '-list', kwargs=self.url_pks) @@ -91,15 +88,11 @@ class ProductTest(BasicModelPermissionTest, APITestCase): casestudy = 4 product = 2 - - def setUp(self): - super().setUp() - self.kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) + @classmethod + def setUpTestData(self): + super().setUpTestData() self.obj = ProductFactory(id=self.product) - @classmethod def setUpClass(cls): super().setUpClass() @@ -121,14 +114,11 @@ class WasteTest(BasicModelPermissionTest, APITestCase): casestudy = 4 waste = 2 - def setUp(self): - super().setUp() - self.kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) + @classmethod + def setUpTestData(self): + super().setUpTestData() self.obj = WasteFactory(id=self.waste) - @classmethod def setUpClass(cls): super().setUpClass() diff --git a/repair/apps/asmfa/tests/test_products.py b/repair/apps/asmfa/tests/test_products.py index 73a8927f3..62a325866 100644 --- a/repair/apps/asmfa/tests/test_products.py +++ b/repair/apps/asmfa/tests/test_products.py @@ -23,10 +23,7 @@ def setUpClass(cls): cls.post_data = cls.put_data cls.patch_data = dict(name="other name") - def setUp(self): - super().setUp() - kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) - self.obj = ProductFactory(id=self.product, - ) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = ProductFactory(id=cls.product) diff --git a/repair/apps/asmfa/tests/test_stocks.py b/repair/apps/asmfa/tests/test_stocks.py index 7f4ac62a9..c8fedad59 100644 --- a/repair/apps/asmfa/tests/test_stocks.py +++ b/repair/apps/asmfa/tests/test_stocks.py @@ -29,7 +29,6 @@ class ActivitystockInKeyflowInCasestudyTest(BasicModelPermissionTest, APITestCas origin = 20 product = 16 activitystock = 13 - keyflowincasestudy = 45 activitygroup = 76 material_1 = 10 material_2 = 11 @@ -45,7 +44,7 @@ def setUpClass(cls): super().setUpClass() cls.url_key = "activitystock" cls.url_pks = dict(casestudy_pk=cls.casestudy, - keyflow_pk=cls.keyflowincasestudy) + keyflow_pk=cls.keyflow) cls.url_pk = dict(pk=cls.activitystock) cls.put_data = dict(origin=cls.origin, composition=cls.comp_data, @@ -58,21 +57,19 @@ def setUpClass(cls): ) #cls.sub_urls = ['keyflow', 'origin_url', 'destination_url'] - def setUp(self): - super().setUp() - kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) - self.mat_obj_1 = MaterialFactory(id=self.material_1, - keyflow=kic_obj) - self.mat_obj_2 = MaterialFactory(id=self.material_2, - keyflow=kic_obj) - self.obj = ActivityStockFactory(id=self.activitystock, - origin__id=self.origin, - origin__activitygroup__id=self.activitygroup, - origin__activitygroup__keyflow=kic_obj, - keyflow=kic_obj, - ) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.mat_obj_1 = MaterialFactory(id=cls.material_1, + keyflow=cls.kic_obj) + cls.mat_obj_2 = MaterialFactory(id=cls.material_2, + keyflow=cls.kic_obj) + cls.obj = ActivityStockFactory(id=cls.activitystock, + origin__id=cls.origin, + origin__activitygroup__id=cls.activitygroup, + origin__activitygroup__keyflow=cls.kic_obj, + keyflow=cls.kic_obj, + ) class ActorstockInKeyflowInCasestudyTest(BasicModelPermissionTest, APITestCase): @@ -104,7 +101,7 @@ def setUpClass(cls): super().setUpClass() cls.url_key = "actorstock" cls.url_pks = dict(casestudy_pk=cls.casestudy, - keyflow_pk=cls.keyflowincasestudy) + keyflow_pk=cls.keyflow) cls.url_pk = dict(pk=cls.actorstock) cls.put_data = dict(origin=cls.origin, composition=cls.comp_data, @@ -117,45 +114,43 @@ def setUpClass(cls): ) #cls.sub_urls = ['keyflow', 'origin_url', 'destination_url'] - def setUp(self): - super().setUp() - self.kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) - self.mat_obj_1 = MaterialFactory(id=self.material_1, - keyflow=self.kic_obj) - self.mat_obj_2 = MaterialFactory(id=self.material_2, - keyflow=self.kic_obj) - self.comp1 = CompositionFactory(name='composition1', + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.mat_obj_1 = MaterialFactory(id=cls.material_1, + keyflow=cls.kic_obj) + cls.mat_obj_2 = MaterialFactory(id=cls.material_2, + keyflow=cls.kic_obj) + cls.comp1 = CompositionFactory(name='composition1', nace='nace1') - self.comp2 = CompositionFactory(name='composition2', + cls.comp2 = CompositionFactory(name='composition2', nace='nace2') - self.activitygroup1 = ActivityGroupFactory(keyflow=self.kic_obj) - self.activity1 = ActivityFactory(activitygroup=self.activitygroup1) - self.actor1 = ActorFactory(id=self.actor1id, activity=self.activity1) - self.activitygroup2 = ActivityGroupFactory(keyflow=self.kic_obj) - self.activity2 = ActivityFactory(activitygroup=self.activitygroup2) - self.actor2 = ActorFactory(id=self.actor2id, activity=self.activity2) - self.actor3 = ActorFactory(activity=self.activity2) - self.act2act1 = Actor2ActorFactory(id=self.actor2actor1, - origin=self.actor1, - destination=self.actor2, - keyflow=self.kic_obj, - composition=self.comp1, + cls.activitygroup1 = ActivityGroupFactory(keyflow=cls.kic_obj) + cls.activity1 = ActivityFactory(activitygroup=cls.activitygroup1) + cls.actor1 = ActorFactory(id=cls.actor1id, activity=cls.activity1) + cls.activitygroup2 = ActivityGroupFactory(keyflow=cls.kic_obj) + cls.activity2 = ActivityFactory(activitygroup=cls.activitygroup2) + cls.actor2 = ActorFactory(id=cls.actor2id, activity=cls.activity2) + cls.actor3 = ActorFactory(activity=cls.activity2) + cls.act2act1 = Actor2ActorFactory(id=cls.actor2actor1, + origin=cls.actor1, + destination=cls.actor2, + keyflow=cls.kic_obj, + composition=cls.comp1, ) - self.act2act2 = Actor2ActorFactory(id=self.actor2actor2, - origin=self.actor2, - destination=self.actor3, - keyflow=self.kic_obj, - composition=self.comp2, + cls.act2act2 = Actor2ActorFactory(id=cls.actor2actor2, + origin=cls.actor2, + destination=cls.actor3, + keyflow=cls.kic_obj, + composition=cls.comp2, ) - self.actorstock1 = ActorStockFactory(id=self.actorstock, - keyflow=self.kic_obj, - origin=self.actor1) - self.actorstock2 = ActorStockFactory(id=self.actorstock2, - keyflow=self.kic_obj, - origin=self.actor2) - self.obj = self.actorstock1 + cls.actorstock1 = ActorStockFactory(id=cls.actorstock, + keyflow=cls.kic_obj, + origin=cls.actor1) + cls.actorstock2 = ActorStockFactory(id=cls.actorstock2, + keyflow=cls.kic_obj, + origin=cls.actor2) + cls.obj = cls.actorstock1 def test_post_get(self): """ @@ -222,7 +217,7 @@ def setUpClass(cls): super().setUpClass() cls.url_key = "groupstock" cls.url_pks = dict(casestudy_pk=cls.casestudy, - keyflow_pk=cls.keyflowincasestudy) + keyflow_pk=cls.keyflow) cls.url_pk = dict(pk=cls.groupstock) cls.put_data = dict(origin=cls.origin, composition=cls.comp_data, @@ -235,17 +230,15 @@ def setUpClass(cls): ) #cls.sub_urls = ['keyflow', 'origin_url', 'destination_url'] - def setUp(self): - super().setUp() - kic_obj = KeyflowInCasestudyFactory(id=self.keyflowincasestudy, - casestudy=self.uic.casestudy, - keyflow__id=self.keyflow) - self.mat_obj_1 = MaterialFactory(id=self.material_1, - keyflow=kic_obj) - self.mat_obj_2 = MaterialFactory(id=self.material_2, - keyflow=kic_obj) - self.obj = GroupStockFactory(id=self.groupstock, - origin__id=self.origin, - origin__keyflow=kic_obj, - keyflow=kic_obj, - ) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.mat_obj_1 = MaterialFactory(id=cls.material_1, + keyflow=cls.kic_obj) + cls.mat_obj_2 = MaterialFactory(id=cls.material_2, + keyflow=cls.kic_obj) + cls.obj = GroupStockFactory(id=cls.groupstock, + origin__id=cls.origin, + origin__keyflow=cls.kic_obj, + keyflow=cls.kic_obj, + ) diff --git a/repair/apps/asmfa/views/flowfilter.py b/repair/apps/asmfa/views/flowfilter.py index 0cb9a5827..9a8ebc17d 100644 --- a/repair/apps/asmfa/views/flowfilter.py +++ b/repair/apps/asmfa/views/flowfilter.py @@ -233,7 +233,7 @@ def _filter(self, lookup_args, query_params=None, SerializerClass=None): if query_params: query_params = query_params.copy() strategy = query_params.pop('strategy', None) - for key in query_params: + for key in list(query_params.keys()): if (key.startswith('material') or key.startswith('waste') or key.startswith('hazardous') or diff --git a/repair/apps/changes/tests/test_graphwalker.py b/repair/apps/changes/tests/test_graphwalker.py index f0b2fb710..6df2358ae 100644 --- a/repair/apps/changes/tests/test_graphwalker.py +++ b/repair/apps/changes/tests/test_graphwalker.py @@ -5,7 +5,6 @@ from repair.apps.asmfa.models import (Actor, Activity, Actor2Actor, ActorStock, AdministrativeLocation, FractionFlow, Material) -from repair.apps.changes.models import Solution, Strategy from repair.apps.asmfa.graphs.graph import StrategyGraph @@ -74,6 +73,7 @@ class MultiplyTestDataMixin: @classmethod def setUpTestData(cls): + super().setUpTestData() """multiply the test data for the peelpioneer_data""" n_clones = 5 activities = Activity.objects.all() @@ -205,6 +205,7 @@ def setUpTestData(cls): year=flow.year, ) new_flows.append(new_flow) + new_flow.save() for fraction_flow_material in fraction_flow_materials: material = Material.objects.get( @@ -225,7 +226,7 @@ def setUpTestData(cls): ) new_fraction_flows.append(new_fraction_flow) - Actor2Actor.objects.bulk_create(new_flows) + #Actor2Actor.objects.bulk_create(new_flows) FractionFlow.objects.bulk_create(new_fraction_flows) diff --git a/repair/apps/changes/tests/test_solutions.py b/repair/apps/changes/tests/test_solutions.py index 921c716bf..4f0e7dc0f 100644 --- a/repair/apps/changes/tests/test_solutions.py +++ b/repair/apps/changes/tests/test_solutions.py @@ -26,11 +26,13 @@ def setUpClass(cls): cls.post_data = dict(name='posttestname') cls.put_data = cls.post_data - def setUp(self): - super().setUp() - self.obj = SolutionCategoryFactory(id=self.solutioncategory, - keyflow=self.kic - ) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = SolutionCategoryFactory( + id=cls.solutioncategory, + keyflow=cls.kic_obj + ) def test_protection_of_deletion(self): """ @@ -94,10 +96,11 @@ def setUpClass(cls): cls.put_data = cls.post_data cls.patch_data = dict(name="test name") - def setUp(self): - super().setUp() - self.obj = SolutionFactory( - id=self.solution, - solution_category__id=self.solutioncategory, - solution_category__keyflow=self.kic + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = SolutionFactory( + id=cls.solution, + solution_category__id=cls.solutioncategory, + solution_category__keyflow=cls.kic_obj ) diff --git a/repair/apps/changes/tests/test_strategies.py b/repair/apps/changes/tests/test_strategies.py index 25028cbd3..a32da5c2c 100644 --- a/repair/apps/changes/tests/test_strategies.py +++ b/repair/apps/changes/tests/test_strategies.py @@ -598,13 +598,14 @@ def setUpClass(cls): cls.patch_data = dict(solution=cls.solution, strategy=cls.strategy_url) - def setUp(self): - super().setUp() - self.obj = SolutionInStrategyFactory( - solution__id=self.solution, - strategy__user=self.uic, - strategy__id=self.strategy, - strategy__keyflow=self.kic, - solution__solution_category__id=self.solutioncategory, - solution__solution_category__keyflow=self.kic, - id=self.solution_strategy) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = SolutionInStrategyFactory( + solution__id=cls.solution, + strategy__user=cls.uic, + strategy__id=cls.strategy, + strategy__keyflow=cls.kic_obj, + solution__solution_category__id=cls.solutioncategory, + solution__solution_category__keyflow=cls.kic_obj, + id=cls.solution_strategy) diff --git a/repair/apps/conclusions/tests.py b/repair/apps/conclusions/tests.py index 5afead9b0..002c3fd0d 100644 --- a/repair/apps/conclusions/tests.py +++ b/repair/apps/conclusions/tests.py @@ -1,13 +1,11 @@ # -*- coding: utf-8 -*- -from django.urls import reverse from test_plus import APITestCase -from rest_framework import status import factory from factory.django import DjangoModelFactory from repair.apps.login.factories import CaseStudyFactory from repair.apps.asmfa.factories import KeyflowInCasestudyFactory -from repair.tests.test import BasicModelPermissionTest, LoginTestCase +from repair.tests.test import BasicModelPermissionTest from repair.apps.conclusions.models import Conclusion, ConsensusLevel, Section @@ -55,10 +53,11 @@ def setUpClass(cls): cls.put_data = cls.post_data cls.patch_data = cls.post_data - def setUp(self): - super().setUp() - self.obj = ConsensusLevelFactory(casestudy=self.uic.casestudy, - id=self.level) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = ConsensusLevelFactory(casestudy=cls.uic.casestudy, + id=cls.level) class SectionTest(BasicModelPermissionTest, APITestCase): @@ -76,10 +75,11 @@ def setUpClass(cls): cls.put_data = cls.post_data cls.patch_data = cls.post_data - def setUp(self): - super().setUp() - self.obj = SectionFactory(casestudy=self.uic.casestudy, - id=self.section) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = SectionFactory(casestudy=cls.uic.casestudy, + id=cls.section) class ConclusionTest(BasicModelPermissionTest, APITestCase): @@ -91,7 +91,7 @@ def setUpClass(cls): super().setUpClass() cls.url_key = "conclusion" cls.url_pks = dict(casestudy_pk=cls.uic.casestudy.id, - keyflow_pk=cls.kic.id) + keyflow_pk=cls.kic_obj.id) cls.url_pk = dict(pk=cls.conclusion) consensus = ConsensusLevelFactory(name='whatever', @@ -105,7 +105,8 @@ def setUpClass(cls): cls.put_data = cls.post_data cls.patch_data = cls.post_data - def setUp(self): - super().setUp() - self.obj = ConclusionFactory(keyflow=self.kic, - id=self.conclusion) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = ConclusionFactory(keyflow=cls.kic_obj, + id=cls.conclusion) diff --git a/repair/apps/login/serializers/users.py b/repair/apps/login/serializers/users.py index 283465f8c..f0fe139ab 100644 --- a/repair/apps/login/serializers/users.py +++ b/repair/apps/login/serializers/users.py @@ -1,4 +1,3 @@ - from django.contrib.auth.models import User, Group from django.utils.translation import ugettext_lazy as _ diff --git a/repair/apps/login/tests/test_login.py b/repair/apps/login/tests/test_login.py index eee8ee063..218a469ee 100644 --- a/repair/apps/login/tests/test_login.py +++ b/repair/apps/login/tests/test_login.py @@ -102,9 +102,10 @@ def test_post(self): uic.save() response = self.get_check_200(url, pk=new_id, **self.url_pks) - def setUp(self): - super().setUp() - self.obj = self.kic.casestudy + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = cls.kic_obj.casestudy def test_session(self): casestudy_name = self.obj.name diff --git a/repair/apps/publications/apps.py b/repair/apps/publications/apps.py deleted file mode 100644 index 5ea24d8fa..000000000 --- a/repair/apps/publications/apps.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.apps import AppConfig - - -class PublicationConfig(AppConfig): - name = 'publications' diff --git a/repair/apps/publications/tests/test_models.py b/repair/apps/publications/tests/test_models.py index c00b09ad0..9441bc202 100644 --- a/repair/apps/publications/tests/test_models.py +++ b/repair/apps/publications/tests/test_models.py @@ -35,20 +35,21 @@ def setUpClass(cls): cls.patch_data = dict(title='patchtest_title') - def setUp(self): - super().setUp() - self.obj = PublicationInCasestudyFactory( - casestudy=self.uic.casestudy, - publication__id=self.publication, - publication__type__title=self.pup_type) + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = PublicationInCasestudyFactory( + casestudy=cls.uic.casestudy, + publication__id=cls.publication, + publication__type__title=cls.pup_type) # create a user with 2 casestudies - self.user = ProfileFactory(user__id=self.user_id, - user__username='User') - self.uic1 = UserInCasestudyFactory(user=self.user, - casestudy__id=self.casestudy1) - self.uic2 = UserInCasestudyFactory(user=self.user, - casestudy__id=self.casestudy2) + cls.user = ProfileFactory(user__id=cls.user_id, + user__username='User') + cls.uic1 = UserInCasestudyFactory(user=cls.user, + casestudy__id=cls.casestudy1) + cls.uic2 = UserInCasestudyFactory(user=cls.user, + casestudy__id=cls.casestudy2) def test_post_existing_publication(self): """Test post method for the detail-view""" diff --git a/repair/apps/statusquo/tests/test_indicators.py b/repair/apps/statusquo/tests/test_indicators.py index c684fe53d..a5ab26b3e 100644 --- a/repair/apps/statusquo/tests/test_indicators.py +++ b/repair/apps/statusquo/tests/test_indicators.py @@ -44,72 +44,73 @@ def setUpClass(cls): super().setUpClass() cls.url_key = "flowindicator" cls.url_pks = dict(casestudy_pk=cls.casestudy, - keyflow_pk=cls.kic.id) + keyflow_pk=cls.kic_obj.id) cls.url_pk = dict(pk=cls.flowindicator_id) - - def setUp(self): - super().setUp() - self.area1 = AreaFactory(id=self.area_id1, - ) - self.area2 = AreaFactory(id=self.area_id2, - ) - self.actor1 = ActorFactory(id=self.actor_id1) - self.actor2 = ActorFactory(id=self.actor_id2) - self.actor3 = ActorFactory(id=self.actor_id3) - self.actor4 = ActorFactory(id=self.actor_id4) - self.actor5 = ActorFactory(id=self.actor_id5) - self.composition1 = CompositionFactory() - self.flow1 = Actor2ActorFactory(id=self.flow_id1, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor1, - destination=self.actor2) - self.flow2 = Actor2ActorFactory(id=self.flow_id2, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor2, - destination=self.actor3 - ) - self.flow3 = Actor2ActorFactory(id=self.flow_id3, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor3, - destination=self.actor5) - self.flow4 = Actor2ActorFactory(id=self.flow_id4, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor5, - destination=self.actor4) - self.flow5 = Actor2ActorFactory(id=self.flow_id5, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor5, - destination=self.actor3) - self.flow6 = Actor2ActorFactory(id=self.flow_id6, - keyflow=self.kic, - composition=self.composition1, - origin=self.actor1, - destination=self.actor3) - self.material1 = MaterialFactory(keyflow=self.kic) - self.flow_a = IndicatorFlowFactory(origin_node_ids='1, 2, 3', - destination_node_ids='4, 5', - materials=[self.material1]) - self.flow_b = IndicatorFlowFactory(origin_node_ids='1, 2', - destination_node_ids='3, 4, 5', - materials=[self.material1]) - self.obj = FlowIndicatorFactory(flow_a=self.flow_a, - flow_b=self.flow_b, - keyflow=self.kic) - self.post_data = dict( + cls.post_data = dict( name = 'FlowIndicator', unit = 'Elmshorn', description = 'supernormal', indicator_type = 'A', - flow_a = [self.flow_a], - flow_b = [self.flow_b], - keyflow = self.keyflow_id1,) - self.put_data = self.post_data - self.patch_data = self.post_data + flow_a = [cls.flow_a], + flow_b = [cls.flow_b], + keyflow = cls.keyflow_id1,) + cls.put_data = cls.post_data + cls.patch_data = cls.post_data + + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.area1 = AreaFactory(id=cls.area_id1, + ) + cls.area2 = AreaFactory(id=cls.area_id2, + ) + cls.actor1 = ActorFactory(id=cls.actor_id1) + cls.actor2 = ActorFactory(id=cls.actor_id2) + cls.actor3 = ActorFactory(id=cls.actor_id3) + cls.actor4 = ActorFactory(id=cls.actor_id4) + cls.actor5 = ActorFactory(id=cls.actor_id5) + cls.composition1 = CompositionFactory() + cls.flow1 = Actor2ActorFactory(id=cls.flow_id1, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor1, + destination=cls.actor2) + cls.flow2 = Actor2ActorFactory(id=cls.flow_id2, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor2, + destination=cls.actor3 + ) + cls.flow3 = Actor2ActorFactory(id=cls.flow_id3, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor3, + destination=cls.actor5) + cls.flow4 = Actor2ActorFactory(id=cls.flow_id4, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor5, + destination=cls.actor4) + cls.flow5 = Actor2ActorFactory(id=cls.flow_id5, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor5, + destination=cls.actor3) + cls.flow6 = Actor2ActorFactory(id=cls.flow_id6, + keyflow=cls.kic_obj, + composition=cls.composition1, + origin=cls.actor1, + destination=cls.actor3) + cls.material1 = MaterialFactory(keyflow=cls.kic_obj) + cls.flow_a = IndicatorFlowFactory(origin_node_ids='1, 2, 3', + destination_node_ids='4, 5', + materials=[cls.material1]) + cls.flow_b = IndicatorFlowFactory(origin_node_ids='1, 2', + destination_node_ids='3, 4, 5', + materials=[cls.material1]) + cls.obj = FlowIndicatorFactory(flow_a=cls.flow_a, + flow_b=cls.flow_b, + keyflow=cls.kic_obj) def test_post(self): pass diff --git a/repair/apps/studyarea/tests/test_stakeholders.py b/repair/apps/studyarea/tests/test_stakeholders.py index accdb96ab..add264347 100644 --- a/repair/apps/studyarea/tests/test_stakeholders.py +++ b/repair/apps/studyarea/tests/test_stakeholders.py @@ -70,7 +70,6 @@ class StakeholderInCasestudyTest(BasicModelPermissionTest, APITestCase): casestudy = 17 stakeholdercategory = 48 - stakeholder = 21 userincasestudy = 67 user = 99 @@ -84,16 +83,16 @@ def setUpClass(cls): cls.url_key = "stakeholder" cls.url_pks = dict(casestudy_pk=cls.casestudy, stakeholdercategory_pk=cls.stakeholdercategory) - cls.url_pk = dict(pk=cls.stakeholder) + cls.url_pk = dict(pk=cls.obj.id) cls.post_data = dict(name='posttestname', stakeholder_category=cls.stakeholdercategory_url) cls.put_data = cls.post_data cls.patch_data = dict(name="test name") - def setUp(self): - super().setUp() - self.obj = StakeholderFactory( - id=self.stakeholder, - stakeholder_category__id=self.stakeholdercategory, - stakeholder_category__casestudy=self.uic.casestudy, + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.obj = StakeholderFactory( + stakeholder_category__id=cls.stakeholdercategory, + stakeholder_category__casestudy=cls.uic.casestudy, ) diff --git a/repair/apps/utils/serializers.py b/repair/apps/utils/serializers.py index 3d229d00a..e777605ea 100644 --- a/repair/apps/utils/serializers.py +++ b/repair/apps/utils/serializers.py @@ -18,9 +18,7 @@ from django.contrib.gis.db.models.fields import (PointField, PolygonField, MultiPolygonField) from django.contrib.gis.geos import GEOSGeometry, WKTWriter -from django.db.models.query import QuerySet from django.conf import settings -from copy import deepcopy from openpyxl import Workbook from openpyxl.writer.excel import save_virtual_workbook @@ -297,7 +295,7 @@ def highlight_errors(s, errors=None): if not isinstance(data.index, pd.RangeIndex): data.reset_index(inplace=True) if file_type == 'xlsx': - data = data.style.apply(highlight_errors, errors=errors) + data.style.apply(highlight_errors, errors=errors) def write(df): with TemporaryMediaFile() as f: diff --git a/repair/apps/utils/views.py b/repair/apps/utils/views.py index 554124934..9e741cc5d 100644 --- a/repair/apps/utils/views.py +++ b/repair/apps/utils/views.py @@ -300,15 +300,15 @@ def destroy(self, request, **kwargs): response = super().destroy(request, **kwargs) except ProtectedError as err: qs = err.protected_objects - show = 5 - n_objects = qs.count() + n_show = 5 + n_objects = len(qs) msg_n_referenced = '{} {}:'.format(n_objects, _('Referencing Object(s)') ) msg = '
'.join(list(err.args[:1]) + [msg_n_referenced] + - [repr(row).strip('<>') for row in qs[:show]] + - ['...' if n_objects > show else ''] + [repr(row).strip('<>') for row in list(qs)[:n_show]] + + ['...' if n_objects > n_show else ''] ) return HttpResponseForbidden(content=msg) return response diff --git a/repair/apps/wmsresources/factories.py b/repair/apps/wmsresources/factories.py index c9a92ab58..dcb6df8e0 100644 --- a/repair/apps/wmsresources/factories.py +++ b/repair/apps/wmsresources/factories.py @@ -8,7 +8,7 @@ class WMSResourceFactory(DjangoModelFactory): name = 'WMSResource1' - uri = 'https://www.wms.nrw.de/gd/bohrungen' + uri = 'https://monitor.ioer.de/cgi-bin/wms?MAP=O06RG_wms' description = 'A short Description' preview = '' zoom = 15 diff --git a/repair/apps/wmsresources/tests/test_admin_forms.py b/repair/apps/wmsresources/tests/test_admin_forms.py index 23700c289..4e7e4c115 100644 --- a/repair/apps/wmsresources/tests/test_admin_forms.py +++ b/repair/apps/wmsresources/tests/test_admin_forms.py @@ -1,15 +1,10 @@ from django.test import TestCase -from django.test import Client from repair.tests.test import AdminAreaTest -from repair.apps.login.models import User, CaseStudy -from repair.apps.wmsresources.models import WMSResourceInCasestudy, WMSResource -from django.contrib.admin.sites import AdminSite -from django.contrib.admin.options import ModelAdmin -from repair.apps.asmfa.factories import KeyflowInCasestudyFactory +from repair.apps.wmsresources.models import WMSResource from repair.apps.login.factories import CaseStudyFactory from repair.apps.wmsresources.factories import WMSResourceFactory from wms_client.admin import WMSForm -from repair.tests.test import AdminAreaTest + class WMSResourceAdminTest(AdminAreaTest, TestCase): """ @@ -27,5 +22,5 @@ def setUpClass(cls): wmsresource = WMSResourceFactory() casestudy = CaseStudyFactory() cls.add_data = {'name': ['test_case'], - 'uri': ['https://www.wms.nrw.de/gd/bohrungen']} + 'uri': ['https://monitor.ioer.de/cgi-bin/wms?MAP=O06RG_wms']} cls.incomplete_data = {'name': ['test_incomplete_data'],} \ No newline at end of file diff --git a/repair/apps/wmsresources/views.py b/repair/apps/wmsresources/views.py index bdefa8af0..55752b15e 100644 --- a/repair/apps/wmsresources/views.py +++ b/repair/apps/wmsresources/views.py @@ -93,7 +93,7 @@ def get(self, request, layer_id): session.params = query_params try: response = retry_session(session=session).get( - uri, auth=(res.username, res.password), + uri, #auth=(res.username, res.password), timeout=0.5) except Exception as e: print(e) diff --git a/repair/settings.py b/repair/settings.py index e99c259b5..799707698 100644 --- a/repair/settings.py +++ b/repair/settings.py @@ -12,9 +12,7 @@ import os import sys -import django - -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -42,6 +40,8 @@ "localhost", "127.0.0.1"] +DEFAULT_AUTO_FIELD='django.db.models.AutoField' + # Application definition INSTALLED_APPS = [ @@ -169,19 +169,23 @@ ('it', _('Italian')), ) +# Linux if sys.platform == 'linux': - # Linux - GDAL_LIBRARY_PATH = os.path.join(sys.exec_prefix, - 'lib', 'libgdal.so') - GEOS_LIBRARY_PATH = os.path.join(sys.exec_prefix, - 'lib', 'libgeos_c.so') + lib_path = os.path.join(sys.exec_prefix, 'lib') + GDAL_LIBRARY_PATH = os.path.join(lib_path, 'libgdal.so') + + GEOS_LIBRARY_PATH = os.path.join(lib_path, 'libgeos_c.so') if not os.path.exists(GEOS_LIBRARY_PATH): - GEOS_LIBRARY_PATH = os.path.join( - sys.exec_prefix, 'lib', 'x86_64-linux-gnu', 'libgeos_c.so') + GEOS_LIBRARY_PATH = os.path.join(lib_path, 'x86_64-linux-gnu', + 'libgeos_c.so') + PROJ4_LIBRARY_PATH = os.path.join(sys.exec_prefix, 'lib', 'libproj.so') + if not os.path.exists(PROJ4_LIBRARY_PATH): + PROJ4_LIBRARY_PATH = os.path.join(lib_path, 'x86_64-linux-gnu', + 'libproj.so') +# Max OS elif sys.platform == 'darwin': - # Max OS GDAL_LIBRARY_PATH = os.path.join(sys.exec_prefix, 'lib', 'libgdal.dylib') GEOS_LIBRARY_PATH = os.path.join(sys.exec_prefix, diff --git a/repair/settings_circleci.py b/repair/settings_circleci.py new file mode 100644 index 000000000..2797fe769 --- /dev/null +++ b/repair/settings_circleci.py @@ -0,0 +1,24 @@ +from repair.settings import * + +DEBUG = True + +DATABASES = { + 'default': { + 'ENGINE': 'django.contrib.gis.db.backends.postgis', + 'NAME': 'circle_test', + 'USER': 'postgres', + 'PASSWORD': 'postgres', + 'HOST': 'localhost', + 'PORT': '5432' + } +} + +WEBPACK_LOADER = { + 'DEFAULT': { + 'CACHE': not DEBUG, + 'BUNDLE_DIR_NAME': 'bundles/dev/', + 'STATS_FILE': os.path.join(PROJECT_DIR, 'webpack-stats-dev.json'), + } +} + +FIXTURE_DIRS.append(os.path.join(PROJECT_DIR, "graph_fixtures"),) \ No newline at end of file diff --git a/repair/settings4tests.py b/repair/settings_spatialite.py similarity index 100% rename from repair/settings4tests.py rename to repair/settings_spatialite.py diff --git a/repair/templates/base.html b/repair/templates/base.html index 335f6526f..29f84e1b1 100644 --- a/repair/templates/base.html +++ b/repair/templates/base.html @@ -1,6 +1,6 @@ -{% load staticfiles %} +{% load static %} {% load i18n %} {% load render_bundle from webpack_loader %} diff --git a/repair/templates/pdfviewer/viewer.html b/repair/templates/pdfviewer/viewer.html index 0c0413e4a..c17fa77d7 100644 --- a/repair/templates/pdfviewer/viewer.html +++ b/repair/templates/pdfviewer/viewer.html @@ -20,7 +20,7 @@ See https://github.com/adobe-type-tools/cmap-resources --> -{% load staticfiles %} +{% load static %} diff --git a/repair/templates/strategy/solutions.html b/repair/templates/strategy/solutions.html index 95e49f18b..c44f2d7e6 100644 --- a/repair/templates/strategy/solutions.html +++ b/repair/templates/strategy/solutions.html @@ -1,5 +1,5 @@ {% load i18n %} -{% load staticfiles %} +{% load static %} {% block content %} diff --git a/repair/tests/test.py b/repair/tests/test.py index 7c2e4db5d..0abd33e45 100644 --- a/repair/tests/test.py +++ b/repair/tests/test.py @@ -6,13 +6,11 @@ from rest_framework import status from django.urls import reverse -from repair.apps.login.factories import UserInCasestudyFactory +from repair.apps.login.factories import UserInCasestudyFactory, CaseStudyFactory from repair.apps.asmfa.factories import KeyflowInCasestudyFactory from django.contrib.auth.models import Permission from repair.apps.login.models import User -from django.test import Client from django.test.client import Client as FormClient -from wms_client.models import WMSResource class CompareAbsURIMixin: @@ -52,14 +50,15 @@ class LoginTestCase: permissions = Permission.objects.all() @classmethod - def setUpClass(cls): - super().setUpClass() + def setUpTestData(cls): + super().setUpTestData() + cls.casestudy_obj = CaseStudyFactory(id=cls.casestudy) cls.uic = UserInCasestudyFactory(id=cls.userincasestudy, user__user__id=cls.user, user__user__username='Anonymus User', - casestudy__id=cls.casestudy) - cls.kic = KeyflowInCasestudyFactory(id=cls.keyflow, - casestudy=cls.uic.casestudy) + casestudy=cls.casestudy_obj) + cls.kic_obj = KeyflowInCasestudyFactory(id=cls.keyflow, + casestudy=cls.casestudy_obj) def setUp(self): self.client.force_login(user=self.uic.user.user) @@ -74,10 +73,15 @@ def tearDown(self): @classmethod def tearDownClass(cls): user = cls.uic.user.user - cs = cls.uic.casestudy user.delete() - cs.delete() - del cls.uic + cls.kic_obj.delete() + cls.uic.delete() + cls.casestudy_obj.delete() + if getattr(cls, 'obj', None): + try: + cls.obj.delete() + except: + pass super().tearDownClass() diff --git a/requirements-dev.txt b/requirements.txt similarity index 87% rename from requirements-dev.txt rename to requirements.txt index 1d2b9d4a8..dffd14d40 100644 --- a/requirements-dev.txt +++ b/requirements.txt @@ -1,11 +1,9 @@ --e . - -django>=2.2.1,<3 -django-webpack-loader>=0.5 -djangorestframework==3.9.3 +django==3.2 +django-webpack-loader==0.7 +djangorestframework==3.14 djangorestframework-gis>=0.12 djangorestframework-datatables>=0.3 -django-filter>=2.1 +django-filter==22.1 wand>=0.5 django-test-plus @@ -27,7 +25,7 @@ plotly psycopg2-binary geojson xlrd -openpyxl +openpyxl==3.0.10 django-debug-toolbar @@ -47,6 +45,5 @@ pytest-xdist codecov>2.1 gitpython -pycairo ipython owslib>=0.19 \ No newline at end of file