#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2017 Étienne Loks # 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 . # See the file COPYING for details. import json from django.contrib.auth.models import Permission from django.db.utils import IntegrityError from django.test.client import Client from django.urls import reverse from archaeological_finds.tests import FindInit from ishtar_common.tests import ( WizardTest, WizardTestFormData as FormData, TestCase, WAREHOUSE_FIXTURES, GenericSerializationTest, COMMON_FIXTURES, create_user, ) from ishtar_common.models import IshtarSiteProfile, SpatialReferenceSystem from archaeological_operations.models import Operation from archaeological_context_records.models import ContextRecord from archaeological_finds.models import Find, MaterialType from archaeological_warehouse import models, views, forms, serializers from archaeological_operations.serializers import operation_serialization from archaeological_context_records.serializers import cr_serialization from archaeological_finds.serializers import find_serialization class SerializationTest(GenericSerializationTest, FindInit, TestCase): fixtures = COMMON_FIXTURES + WAREHOUSE_FIXTURES def setUp(self): ope1 = self.create_operation()[0] ope2 = self.create_operation()[1] cr = self.create_context_record(data={"label": "CR 1", "operation": ope1})[0] cr2 = self.create_context_record(data={"label": "CR 2", "operation": ope2})[1] self.create_finds(data_base={"context_record": cr}) self.create_finds(data_base={"context_record": cr2}) self.create_finds(data_base={"context_record": cr2}) w1 = models.Warehouse.objects.create( name="Test1", external_id="test", warehouse_type=models.WarehouseType.objects.all()[0], ) w2 = models.Warehouse.objects.create( name="Test2", external_id="test2", warehouse_type=models.WarehouseType.objects.all()[0], ) w3 = models.Warehouse.objects.create( name="Test3", external_id="test3", warehouse_type=models.WarehouseType.objects.all()[0], ) self.warehouses = [w1, w2, w3] c1 = models.Container.objects.create( location=w1, responsible=w1, container_type=models.ContainerType.objects.all()[0], reference="Réf1", index=1, external_id="ref1-1", ) c2 = models.Container.objects.create( location=w2, responsible=w1, container_type=models.ContainerType.objects.all()[0], reference="Réf2", index=2, external_id="ref2-2", ) f0 = self.finds[0] f0.container = c1 f0.container_ref = c2 f0.save() c3 = models.Container.objects.create( location=w1, responsible=w2, container_type=models.ContainerType.objects.all()[0], reference="Réf3", index=1, external_id="ref3-1", ) c4 = models.Container.objects.create( location=w2, responsible=w2, container_type=models.ContainerType.objects.all()[0], reference="Réf4", index=2, external_id="ref4-2", ) f1 = self.finds[1] f1.container = c3 f1.container_ref = c4 f1.save() c5 = models.Container.objects.create( location=w3, responsible=w3, container_type=models.ContainerType.objects.all()[0], reference="Réf5", index=1, external_id="ref5-2", ) f2 = self.finds[2] f2.container = c5 f2.container_ref = c5 f2.save() ct1 = models.ContainerType.objects.all()[0] ct2 = models.ContainerType.objects.all()[1] wl1 = models.WarehouseDivisionLink.objects.create( warehouse=w1, container_type=ct1 ) wl2 = models.WarehouseDivisionLink.objects.create( warehouse=w1, container_type=ct2 ) wl3 = models.WarehouseDivisionLink.objects.create( warehouse=w2, container_type=ct2 ) wl4 = models.WarehouseDivisionLink.objects.create( warehouse=w3, container_type=ct1 ) models.Container.objects.create( location=c1.location, parent=c1, container_type=ct1, reference="A1", ) models.Container.objects.create( location=c1.location, parent=c1, container_type=ct2, reference="A2" ) models.Container.objects.create( location=c2.location, parent=c2, container_type=ct2, reference="A4" ) models.Container.objects.create( location=c3.location, parent=c3, container_type=ct1, reference="A5" ) def _fixture_teardown(self): try: super()._fixture_teardown() except IntegrityError: print("Strange error patch...") # TODO: remove pass def test_serialization(self): res = self.generic_serialization_test(serializers.warehouse_serialization) warehouse_json = json.loads( res[("warehouse", "archaeological_warehouse__Warehouse")] ) self.assertEqual(len(warehouse_json), models.Warehouse.objects.count()) container_json = json.loads( res[("warehouse", "archaeological_warehouse__Container")] ) self.assertEqual(len(container_json), models.Container.objects.count()) div_json = json.loads( res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")] ) self.assertEqual(len(div_json), models.WarehouseDivisionLink.objects.count()) result_queryset = Operation.objects.filter(uuid=self.operations[0].uuid) res = self.generic_serialization_test( serializers.warehouse_serialization, no_test=True, kwargs={"operation_queryset": result_queryset}, ) warehouse_json = json.loads( res[("warehouse", "archaeological_warehouse__Warehouse")] ) self.assertEqual(len(warehouse_json), 2) container_json = json.loads( res[("warehouse", "archaeological_warehouse__Container")] ) self.assertEqual(len(container_json), 2) div_json = json.loads( res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")] ) self.assertEqual(len(div_json), 3) result_queryset = ContextRecord.objects.filter( uuid=self.context_records[0].uuid ) res = self.generic_serialization_test( serializers.warehouse_serialization, no_test=True, kwargs={"cr_queryset": result_queryset}, ) warehouse_json = json.loads( res[("warehouse", "archaeological_warehouse__Warehouse")] ) self.assertEqual(len(warehouse_json), 2) container_json = json.loads( res[("warehouse", "archaeological_warehouse__Container")] ) self.assertEqual(len(container_json), 2) div_json = json.loads( res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")] ) self.assertEqual(len(div_json), 3) result_queryset = Find.objects.filter(uuid=self.finds[0].uuid) res = self.generic_serialization_test( serializers.warehouse_serialization, no_test=True, kwargs={"find_queryset": result_queryset}, ) warehouse_json = json.loads( res[("warehouse", "archaeological_warehouse__Warehouse")] ) self.assertEqual(len(warehouse_json), 2) container_json = json.loads( res[("warehouse", "archaeological_warehouse__Container")] ) self.assertEqual(len(container_json), 2) div_json = json.loads( res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")] ) self.assertEqual(len(div_json), 3) result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].id) res = self.generic_serialization_test( serializers.warehouse_serialization, no_test=True, kwargs={"warehouse_queryset": result_queryset}, ) warehouse_json = json.loads( res[("warehouse", "archaeological_warehouse__Warehouse")] ) self.assertEqual(len(warehouse_json), 1) container_json = json.loads( res[("warehouse", "archaeological_warehouse__Container")] ) self.assertEqual(len(container_json), 3 + 3) div_json = json.loads( res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")] ) self.assertEqual(len(div_json), 2) def test_ope_serialization_with_warehouse_filter(self): res = self.generic_serialization_test( operation_serialization, no_test=True, ) ope_json = json.loads( res[("operations", "archaeological_operations__Operation")] ) self.assertEqual(len(ope_json), 2) result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk) res = self.generic_serialization_test( operation_serialization, no_test=True, kwargs={"warehouse_queryset": result_queryset}, ) ope_json = json.loads( res[("operations", "archaeological_operations__Operation")] ) self.assertEqual(len(ope_json), 1) def test_cr_serialization_with_warehouse_filter(self): res = self.generic_serialization_test( cr_serialization, no_test=True, ) cr_json = json.loads( res[("context_records", "archaeological_context_records__ContextRecord")] ) self.assertEqual(len(cr_json), 2) result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk) res = self.generic_serialization_test( cr_serialization, no_test=True, kwargs={"warehouse_queryset": result_queryset}, ) cr_json = json.loads( res[("context_records", "archaeological_context_records__ContextRecord")] ) self.assertEqual(len(cr_json), 1) def test_find_serialization_with_warehouse_filter(self): res = self.generic_serialization_test( find_serialization, no_test=True, ) find_json = json.loads(res[("finds", "archaeological_finds__Find")]) self.assertEqual(len(find_json), 3) bfind_json = json.loads(res[("finds", "archaeological_finds__BaseFind")]) self.assertEqual(len(bfind_json), 3) result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk) res = self.generic_serialization_test( find_serialization, no_test=True, kwargs={"warehouse_queryset": result_queryset}, ) find_json = json.loads(res[("finds", "archaeological_finds__Find")]) self.assertEqual(len(find_json), 1) bfind_json = json.loads(res[("finds", "archaeological_finds__BaseFind")]) self.assertEqual(len(bfind_json), 1) def test_restore(self): current_number, zip_filename = self.generic_restore_test_genzip( serializers.WAREHOUSE_MODEL_LIST, serializers.warehouse_serialization ) self.generic_restore_test( zip_filename, current_number, serializers.WAREHOUSE_MODEL_LIST ) class WarehouseWizardCreationTest(WizardTest, FindInit, TestCase): fixtures = WAREHOUSE_FIXTURES url_name = "warehouse_creation" wizard_name = "warehouse_wizard" steps = views.warehouse_creation_steps redirect_url = ( "/warehouse_modification/selec-warehouse_modification" "?open_item={last_id}" ) model = models.Warehouse # back is messing with divisions but it is not a real problem because # reinit is necessary test_back = False form_datas = [ FormData( "Warehouse creation", form_datas={ "warehouse-warehouse_creation": { "name": "warehouse-ref", "warehouse_type": None, "location": None, "responsible": None, }, "divisions-warehouse_creation": [{"container_type": None, "order": 42}], }, ), FormData( "Warehouse creation with no division", form_datas={ "warehouse-warehouse_creation": { "name": "warehouse-ref", "warehouse_type": None, "location": None, "responsible": None, }, }, ignored=["divisions-warehouse_creation"], ), ] def pre_wizard(self): main_data = self.form_datas[0].form_datas alt_data = self.form_datas[1].form_datas main_data["warehouse-warehouse_creation"][ "warehouse_type" ] = models.WarehouseType.objects.all()[0].pk alt_data["warehouse-warehouse_creation"][ "warehouse_type" ] = models.WarehouseType.objects.all()[0].pk main_data["divisions-warehouse_creation"][0][ "container_type" ] = models.ContainerType.objects.all()[0].pk self.warehouse_number = models.Warehouse.objects.count() self.warehouse_div_link = models.WarehouseDivisionLink.objects.count() super(WarehouseWizardCreationTest, self).pre_wizard() def post_wizard(self): self.assertEqual(models.Warehouse.objects.count(), self.warehouse_number + 2) self.assertEqual( models.WarehouseDivisionLink.objects.count(), self.warehouse_div_link + 1 ) class ContainerWizardCreationTest(WizardTest, FindInit, TestCase): fixtures = WAREHOUSE_FIXTURES url_name = "container_creation" wizard_name = "container_wizard" steps = views.container_creation_steps redirect_url = ( "/container_modification/selec-container_modification" "?open_item={last_id}" ) model = models.Container form_datas = [ FormData( "Container creation", form_datas={ "container-container_creation": { "reference": "hop-ref", "container_type": None, "location": None, }, }, ), FormData( "Other container on the same warehouse", form_datas={ "container-container_creation": { "reference": "hop-ref2", "container_type": None, "location": None, }, }, ), FormData( "Container creation", form_datas={ "container-container_creation": { "reference": "hop-ref3", "container_type": None, "location": None, "parent": None, }, }, ), ] def pre_wizard(self): main_warehouse = models.Warehouse.objects.create( name="Main", warehouse_type=models.WarehouseType.objects.all()[0] ) main_data = self.form_datas[0].form_datas main_data_bis = self.form_datas[1].form_datas alt_data = self.form_datas[2].form_datas for data in [main_data, main_data_bis, alt_data]: forms_data = data["container-container_creation"] forms_data["responsible"] = main_warehouse.pk forms_data["location"] = main_warehouse.pk forms_data["container_type"] = models.ContainerType.objects.all()[0].pk alt_warehouse = models.Warehouse.objects.create( name="Alt", warehouse_type=models.WarehouseType.objects.all()[0] ) alt_data["container-container_creation"]["location"] = alt_warehouse.pk alt_data["container-container_creation"][ "parent" ] = models.Container.objects.create( reference="Plop", container_type=models.ContainerType.objects.all()[1], location=alt_warehouse, ).pk self.container_number = models.Container.objects.count() super(ContainerWizardCreationTest, self).pre_wizard() def post_wizard(self): self.assertEqual(models.Container.objects.count(), self.container_number + 3) class WarehouseTest(TestCase): fixtures = WAREHOUSE_FIXTURES def setUp(self): self.warehouse = models.Warehouse.objects.create( name="Hophop", warehouse_type=models.WarehouseType.objects.all()[0], address="Adresse", ) self.container_types = models.ContainerType.objects.all()[:4] def test_orga_from_warehouse(self): self.warehouse.create_attached_organization() w = models.Warehouse.objects.get(pk=self.warehouse.pk) self.assertIsNotNone(w.organization) self.assertEqual(w.organization.name, "Hophop") self.assertEqual(w.organization.address, "Adresse") self.assertEqual(w.address, "") def test_localisation_import(self): container_nb = models.Container.objects.count() base_value = "A;42;allée 3\;2" error = self.warehouse._add_localisations(None, base_value, return_errors=True) self.assertTrue(error) # no division set for idx, ct in enumerate(self.container_types): models.WarehouseDivisionLink.objects.create( container_type=ct, order=idx * 10, warehouse=self.warehouse ) too_many_value = "A;42;allée 3\;2;5;42;3" error = self.warehouse._add_localisations( None, too_many_value, return_errors=True ) self.assertTrue(error) __, error = self.warehouse._add_localisations( None, base_value, return_errors=True ) self.assertIsNone(error) parent = None for idx, reference in enumerate(("A", "42", "allée 3;2")): q = models.Container.objects.filter( parent=parent, location=self.warehouse, container_type=self.container_types[idx], reference=reference, ) self.assertEqual( q.count(), 1, "Division {} {} - parent {} not created".format( self.container_types[idx], reference, parent ), ) parent = q.all()[0] new_container_nb = models.Container.objects.count() self.assertEqual(container_nb + len(self.container_types), new_container_nb) value = "A;42;allée 4" __, error = self.warehouse._add_localisations(None, value, return_errors=True) self.assertIsNone(error) # only create a new container self.assertEqual(new_container_nb + 1, models.Container.objects.count()) q = models.Container.objects.filter( parent__reference="42", parent__container_type=self.container_types[1], parent__location=self.warehouse, location=self.warehouse, container_type=self.container_types[2], reference="allée 4", ) self.assertEqual(q.count(), 1) # test with an empty localisation value = "A;42;;35" __, error = self.warehouse._add_localisations(None, value, return_errors=True) self.assertIsNone(error) q = models.Container.objects.filter( parent__reference="42", parent__container_type=self.container_types[1], parent__location=self.warehouse, location=self.warehouse, container_type=self.container_types[3], reference="35", ) self.assertEqual(q.count(), 1) class ContainerTest(FindInit, TestCase): fixtures = WAREHOUSE_FIXTURES def setUp(self): self.main_warehouse = models.Warehouse.objects.create( name="Main", warehouse_type=models.WarehouseType.objects.all()[0] ) self.division = models.WarehouseDivision.objects.create(label="division") self.alt_division = models.WarehouseDivision.objects.create(label="division2") self.div_link = models.WarehouseDivisionLink.objects.create( warehouse=self.main_warehouse, division=self.division ) self.alt_warehouse = models.Warehouse.objects.create( name="Alt", warehouse_type=models.WarehouseType.objects.all()[0] ) def test_container_search(self): ct = models.ContainerType.objects.order_by("id").all()[0] ct2 = models.ContainerType.objects.order_by("id").all()[1] container_1 = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=ct, ) container_2 = models.Container.objects.create( reference="35000", responsible=self.main_warehouse, parent=container_1, location=self.main_warehouse, container_type=ct2, ) container_2.index = 42000 container_2.save() username, password, user = create_user() user.user_permissions.add(Permission.objects.get(codename="view_warehouse")) client = Client() client.login(username=username, password=password) url = "/autocomplete-container/{}/".format(self.main_warehouse.pk) response = client.get(url, {"term": "Test"}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 2) response = client.get(url, {"term": "Test 35000"}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 1) response = client.get(url, {"term": "42000"}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 1) full_path = "{} Test {} 35000".format(ct.label, ct2.label) response = client.get(url, {"term": full_path}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 1) # inverse position full_path = "{} 35000 {} Test".format(ct2.label, ct.label) response = client.get(url, {"term": full_path}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 1) # unaccent ct2_label = ct2.label self.assertIn("e", ct2_label) ct2_label = ct2_label.replace("e", "é") full_path = "{} 35000 {} Test".format(ct2_label, ct.label) response = client.get(url, {"term": full_path}) self.assertEqual(response.status_code, 200) c = json.loads(response.content.decode()) self.assertEqual(len(c), 1) def test_form_creation(self): data = { "reference": "hop-ref", "responsible": self.main_warehouse.pk, "location": self.main_warehouse.pk, "container_type": models.ContainerType.objects.all()[0].pk, } form = forms.ContainerForm(data=data) self.assertTrue(form.is_valid(), msg="{}".format(form.errors)) self.container_number = models.Container.objects.count() self.create_user() form.save(self.user) self.assertEqual(models.Container.objects.count(), self.container_number + 1) def test_change_location(self): container = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=models.ContainerType.objects.all()[0], ) container.save() container = models.Container.objects.get(pk=container.pk) container_2 = models.Container.objects.create( reference="Test2", responsible=self.main_warehouse, location=self.main_warehouse, container_type=models.ContainerType.objects.all()[0], parent=container, ) self.assertIn(self.main_warehouse.name, container.cached_location) models.ContainerLocalisation.objects.create( container=container, division=self.div_link, ) self.assertTrue( models.ContainerLocalisation.objects.filter( division__warehouse=self.main_warehouse ).count() ) # changing location remove irrelevant localisation other_warehouse = models.Warehouse.objects.create( name="Other", warehouse_type=models.WarehouseType.objects.all()[0] ) container.location = other_warehouse container.save() self.assertFalse( models.ContainerLocalisation.objects.filter( division__warehouse=self.main_warehouse ).count() ) container_2 = models.Container.objects.get(pk=container_2.pk) self.assertEqual(container_2.location, other_warehouse) """ def test_reassign_existing_division_on_warehouse_change(self): container = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=models.ContainerType.objects.all()[0] ) container_loca = models.ContainerLocalisation.objects.create( container=container, division=self.div_link, ) alt_warehouse = models.Warehouse.objects.create( name="Alternative", warehouse_type=models.WarehouseType.objects.all()[0] ) new_div_link = models.WarehouseDivisionLink.objects.create( warehouse=alt_warehouse, division=self.division) nb_container_loca = models.ContainerLocalisation.objects.count() container.location = alt_warehouse container.save() # no new container localisation self.assertEqual(nb_container_loca, models.ContainerLocalisation.objects.count()) # but the new one is reaffected container_loca = models.ContainerLocalisation.objects.get( pk=container_loca.pk) self.assertEqual(container_loca.division, new_div_link) # reaffect first division link self.div_link.division = self.alt_division self.div_link.save() container.location = self.main_warehouse container.save() # cannot reaffect -> the location is not preserved self.assertEqual(nb_container_loca, models.ContainerLocalisation.objects.count() + 1) """ def test_update_containers_on_warehouse_update(self): container = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=models.ContainerType.objects.all()[0], ) container.save() container = models.Container.objects.get(pk=container.pk) self.assertIn(self.main_warehouse.name, container.cached_location) warehouse = models.Warehouse.objects.get(pk=self.main_warehouse.pk) warehouse.name = "New name" warehouse.slug = "new-name" warehouse.save() self.assertEqual(models.Container.objects.filter(need_update=True).count(), 1) self.assertEqual( models.Container.objects.filter(pk=container.pk, need_update=True).count(), 1, ) container = models.Container.objects.get(pk=container.pk) # process pending update container.skip_history_when_saving = True container._no_move = True container.save() container = models.Container.objects.get(pk=container.pk) self.assertIn("New name", container.cached_location) def test_external_id(self): ct = models.ContainerType.objects.all()[0] container_1 = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=ct, ) container_2 = models.Container.objects.create( reference="Test 2", responsible=self.main_warehouse, parent=container_1, location=self.main_warehouse, container_type=ct, ) container_3 = models.Container.objects.create( reference="Test 3", responsible=self.main_warehouse, parent=container_2, location=self.main_warehouse, container_type=ct, ) self.assertEqual( container_1.external_id, "{}-{}-{}".format( self.main_warehouse.external_id, ct.txt_idx, container_1.reference ), ) self.assertEqual( container_2.external_id, "{}-{}-{}".format( container_1.external_id, ct.txt_idx, container_2.reference ), ) self.assertEqual( container_3.external_id, "{}-{}-{}".format( container_2.external_id, ct.txt_idx, container_3.reference ), ) def test_merge_candidate(self): ct = models.ContainerType.objects.all()[0] container_1 = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, container_type=ct, ) init_mc = container_1.merge_candidate.count() container_2 = models.Container.objects.create( reference="TEST", responsible=self.main_warehouse, location=self.main_warehouse, container_type=ct, ) self.assertEqual(container_1.merge_candidate.count(), init_mc + 1) container_1.archive() self.assertEqual(container_1.merge_candidate.count(), init_mc) container_1 = models.Container.objects.get(pk=container_1.pk) container_1.archived = False container_1.save() container_2 = models.Container.objects.get(pk=container_2.pk) self.assertEqual(container_1.merge_candidate.count(), init_mc + 1) container_2.location = self.alt_warehouse container_2.save() self.assertEqual(container_1.merge_candidate.count(), init_mc) def test_merge_container(self): ct = models.ContainerType.objects.all()[0] ct2 = models.ContainerType.objects.all()[1] self.create_finds() self.create_finds() self.create_finds() find0 = self.finds[0] find1 = self.finds[1] find2 = self.finds[2] container_1 = models.Container.objects.create( reference="Test 1", location=self.main_warehouse, container_type=ct ) find0.container = container_1 find0.container_ref = container_1 find0.save() find1.container = container_1 find1.container_ref = container_1 find1.save() container_2 = models.Container.objects.create( reference="Test 2", location=self.alt_warehouse, container_type=ct2 ) find2.container = container_2 find2.container_ref = container_2 find2.save() container_1.merge(container_2) container_1 = models.Container.objects.get(pk=container_1.pk) self.assertEqual(models.Container.objects.filter(pk=container_2.pk).count(), 0) # preserve existing fields self.assertEqual(container_1.reference, "Test 1") self.assertEqual(container_1.container_type, ct) find_lst = [f for f in container_1.finds.all()] for f in [find0, find1, find2]: self.assertIn(f, find_lst) def test_merge_included_containers(self): ct = models.ContainerType.objects.all()[0] ct2 = models.ContainerType.objects.all()[1] ct3 = models.ContainerType.objects.all()[2] self.create_finds() self.create_finds() self.create_finds() self.create_finds() find0 = self.finds[0] find1 = self.finds[1] find2 = self.finds[2] find3 = self.finds[3] top_container_1 = models.Container.objects.create( reference="Topref 1", location=self.main_warehouse, container_type=ct ) find0.container = top_container_1 find0.container_ref = top_container_1 find0.save() top_container_2 = models.Container.objects.create( reference="Topref 2", location=self.alt_warehouse, container_type=ct ) find1.container = top_container_2 find1.container_ref = top_container_2 find1.save() middle_container_1 = models.Container.objects.create( reference="Middle ref", location=self.main_warehouse, parent=top_container_1, container_type=ct2, ) find2.container = middle_container_1 find2.container_ref = middle_container_1 find2.save() middle_container_2 = models.Container.objects.create( reference="Middle ref", location=self.alt_warehouse, parent=top_container_2, container_type=ct2, ) bottom_container_3 = models.Container.objects.create( reference="Bottom ref", location=self.alt_warehouse, parent=middle_container_2, container_type=ct3, ) find3.container = bottom_container_3 find3.container_ref = bottom_container_3 find3.save() top_container_1.merge(top_container_2) find0 = Find.objects.get(pk=find0.pk) self.assertEqual(find0.container, top_container_1) find1 = Find.objects.get(pk=find1.pk) self.assertEqual(find1.container, top_container_1) q = models.Container.objects.filter(reference="Topref 2") self.assertEqual(q.count(), 0) q = models.Container.objects.filter(reference="Topref 1") self.assertEqual(q.count(), 1) top_ref = q.all()[0] self.assertEqual(top_ref.finds.count(), 2) self.assertEqual(top_ref.location, self.main_warehouse) q = models.Container.objects.filter(reference="Middle ref") self.assertEqual(q.count(), 1) middle = q.all()[0] self.assertEqual(middle.parent, top_ref) self.assertEqual(middle.location, self.main_warehouse) q = models.Container.objects.filter(reference="Bottom ref") self.assertEqual(q.count(), 1) bottom = q.all()[0] self.assertEqual(bottom.parent, middle) self.assertEqual(bottom.location, self.main_warehouse) def test_bulk_update(self): username, password, user = create_user() user.user_permissions.add(Permission.objects.get(codename="change_container")) client = Client() ct = models.ContainerType.objects.all()[0] ct2 = models.ContainerType.objects.all()[1] container_parent = models.Container.objects.create( reference="Parent container", location=self.main_warehouse, container_type=ct, ) container_parent2 = models.Container.objects.create( reference="Parent container 2", location=self.alt_warehouse, container_type=ct, ) container = models.Container.objects.create( reference="Test", location=self.main_warehouse, parent=container_parent, container_type=ct2, ) # base modification url = reverse("container-qa-bulk-update", args=[container.pk]) data = {"qacontainer_type": ct.pk, "qalocation": "", "qaparent": ""} response = client.post(url, data) self.assertRedirects(response, "/") client.login(username=username, password=password) response = client.post(url, data) self.assertEqual(response.status_code, 200) confirm_url = reverse("container-qa-bulk-update-confirm", args=[container.pk]) response = client.post(confirm_url, data) self.assertRedirects(response, "/success/") container = models.Container.objects.get(pk=container.pk) self.assertEqual(container.container_type_id, ct.pk) container.container_type = ct2 container.save() data = { "qacontainer_type": "", "qalocation": self.alt_warehouse.pk, "qaparent": container_parent2.pk, } response = client.post(confirm_url, data) self.assertRedirects(response, "/success/") container = models.Container.objects.get(pk=container.pk) self.assertEqual(container.location, self.alt_warehouse) self.assertEqual(container.parent, container_parent2) container.location = self.main_warehouse container.parent = container_parent container.save() # change location of children data = { "qacontainer_type": "", "qalocation": self.alt_warehouse.pk, "qaparent": "", } confirm_parent_url = reverse( "container-qa-bulk-update-confirm", args=[container_parent.pk] ) response = client.post(confirm_parent_url, data) self.assertRedirects(response, "/success/") container_parent = models.Container.objects.get(pk=container_parent.pk) self.assertEqual(container_parent.location, self.alt_warehouse) container = models.Container.objects.get(pk=container.pk) self.assertEqual(container.location, self.alt_warehouse) container_parent.location = self.main_warehouse container_parent.save() container.location = self.main_warehouse container.parent = container_parent container.save() # reinit parent when not provided and location changed data = { "qacontainer_type": "", "qalocation": self.alt_warehouse.pk, "qaparent": "", } response = client.post(confirm_url, data) self.assertRedirects(response, "/success/") container = models.Container.objects.get(pk=container.pk) self.assertEqual(container.location, self.alt_warehouse) self.assertEqual(container.parent, None) def test_index(self): ct = models.ContainerType.objects.all()[0] ct.stationary = False ct.save() ct2 = models.ContainerType.objects.all()[1] ct2.stationary = True ct2.save() q = models.Container.objects.filter(location=self.main_warehouse).order_by( "-index" ) if q.count(): base_index = q.all()[0].index else: base_index = 0 container_3 = models.Container.objects.create( reference="Ref 3", location=self.main_warehouse, container_type=ct2 ) self.assertEqual(container_3.index, None) container_1 = models.Container.objects.create( reference="Ref 1", location=self.main_warehouse, container_type=ct ) self.assertEqual( models.Container.objects.get(pk=container_1.pk).index, base_index + 1 ) container_2 = models.Container.objects.create( reference="Ref 2", location=self.main_warehouse, container_type=ct ) self.assertEqual( models.Container.objects.get(pk=container_2.pk).index, base_index + 2 ) self.assertEqual(models.Container.objects.get(pk=container_3.pk).index, None) container_4 = models.Container.objects.create( reference="Ref 4", location=self.main_warehouse, container_type=ct2 ) self.assertEqual(container_4.index, None) self.assertEqual(models.Container.objects.get(pk=container_4.pk).index, None) container_5 = models.Container.objects.create( reference="Ref 5", location=self.main_warehouse, container_type=ct ) self.assertEqual( models.Container.objects.get(pk=container_5.pk).index, base_index + 3 ) def test_get_material_types(self): mat0 = MaterialType.objects.all()[0] mat1 = MaterialType.objects.all()[1] mat2 = MaterialType.objects.all()[2] ct = models.ContainerType.objects.all()[0] self.create_finds() self.create_finds() self.create_finds() find0 = self.finds[0] find0.material_types.add(mat0) find0.material_types.add(mat1) find1 = self.finds[1] find0.material_types.add(mat1) find0.material_types.add(mat2) find2 = self.finds[2] container_1 = models.Container.objects.create( reference="Test 1", location=self.main_warehouse, container_type=ct ) container_2 = models.Container.objects.create( reference="Test 2", location=self.alt_warehouse, container_type=ct ) find0.container = container_1 find0.save() find1.container = container_1 find1.container_ref = container_2 find1.save() find2.container = container_2 find1.save() # no material inside this container self.assertEqual(container_2.get_material_types(), "") self.assertEqual( container_1.get_material_types(), ", ".join(sorted([mat0.label, mat1.label, mat2.label])), ) self.assertEqual( container_1.get_material_types_code(), "|".join(sorted([mat0.code, mat1.code, mat2.code])), ) def test_prevent_parent_infinite_loop(self): ct = models.ContainerType.objects.all()[0] container_1 = models.Container.objects.create( reference="Test 1", location=self.main_warehouse, container_type=ct ) container_2 = models.Container.objects.create( reference="Test 2", location=self.main_warehouse, container_type=ct, parent=container_1 ) container_3 = models.Container.objects.create( reference="Test 2", location=self.main_warehouse, container_type=ct, parent=container_2 ) container_1.parent = container_3 container_1.save() self.assertIsNone(models.Container.objects.get(pk=container_1.pk).parent) def test_calculated_weight(self): self.create_finds() self.create_finds() self.create_finds() find0 = self.finds[0] find1 = self.finds[1] find1.weight = 600 find1.save() find2 = self.finds[2] find2.weight = 700 find2.save() ct = models.ContainerType.objects.all()[0] ct.tare_weight = 200 ct.save() container_1 = models.Container.objects.create( reference="Test 1", location=self.main_warehouse, container_type=ct ) container_1.save() self.assertEqual(container_1.calculated_weight, 200) self.assertEqual(container_1.cached_weight, 200) find0.container = container_1 find0.save() container_1 = models.Container.objects.get(pk=container_1.pk) # no weight -> tare weight self.assertEqual(container_1.calculated_weight, 200) self.assertEqual(container_1.cached_weight, 200) find1.container = container_1 find1.save() container_1 = models.Container.objects.get(pk=container_1.pk) # tare weight + find1 weight self.assertEqual(container_1.calculated_weight, 800) self.assertEqual(container_1.cached_weight, 800) find2.container = container_1 find2.save() container_1 = models.Container.objects.get(pk=container_1.pk) # tare weight + find1 weight + find2 weight self.assertEqual(container_1.calculated_weight, 1500) self.assertEqual(container_1.cached_weight, 1500) profile, created = IshtarSiteProfile.objects.get_or_create( slug="default", active=True ) profile.calculate_weight_on_full = True profile.save() container_1.save() container_1 = models.Container.objects.get(pk=container_1.pk) # a find with no weight is inside the container self.assertEqual(container_1.calculated_weight, None) self.assertEqual(container_1.cached_weight, None) find0.container = None find0.save() # once the find with no weight is removed the weight is recalculated container_1 = models.Container.objects.get(pk=container_1.pk) self.assertEqual(container_1.calculated_weight, 1500) self.assertEqual(container_1.cached_weight, 1500) find0.container = container_1 find0.save() container_1 = models.Container.objects.get(pk=container_1.pk) self.assertEqual(container_1.calculated_weight, None) self.assertEqual(container_1.cached_weight, None)