651 lines
28 KiB
Python
651 lines
28 KiB
Python
import json
|
|
from datetime import timedelta
|
|
from unittest import mock
|
|
|
|
from django.test import TestCase
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib import messages
|
|
from django.contrib.messages import get_messages
|
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
|
|
from common.models import UserConfig, Role, Thematic, UserThematics
|
|
from contracts.models import Company, CompanyTeam, CompanyMember, Contract, ContractPost, ContractOrder, ContractOrderQuote, ContractOrderQuoteItem
|
|
from assets.models import AssetCategory
|
|
from interventions.models import (
|
|
Intervention,
|
|
InterventionContractPost,
|
|
InterventionPlanificationTimeLine,
|
|
InterventionRealizationTimeLine,
|
|
Operation,
|
|
InterventionAsset,
|
|
OperationTemplate,
|
|
OperationTemplateItem,
|
|
OperationStatusSet,
|
|
OperationStatus,
|
|
STATUS_ORDERS,
|
|
InterventionDocument,
|
|
)
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from interventions.views import _group_operations_by_asset_and_template, _create_equipment_operations_for_assets
|
|
from interventions.permissions import can_manage_occupations, can_delete_document
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
class InspectionTests(TestCase):
|
|
def setUp(self):
|
|
from common.models import UserConfig, Role, Thematic, UserThematics
|
|
from contracts.models import Company, Contract
|
|
from interventions.models import InspectionConfiguration, OperationTemplate, OperationTemplateItem, OperationStatusSet
|
|
|
|
User = get_user_model()
|
|
self.user = User.objects.create_user(username='inspector_user', password='pwd')
|
|
self.role_inspector = Role.objects.create(name='inspector')
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
self.user_config.roles.add(self.role_inspector)
|
|
|
|
self.thematic = Thematic.objects.create(code='roads', name_fr='Voirie', name_nl='Wegen')
|
|
UserThematics.objects.create(
|
|
user_config=self.user_config,
|
|
thematic=self.thematic,
|
|
can_view_interventions=True,
|
|
can_edit_interventions=True,
|
|
)
|
|
|
|
self.company = Company.objects.create(name='Provider A')
|
|
|
|
from datetime import date
|
|
today = date.today()
|
|
self.contract = Contract.objects.create(
|
|
company=self.company,
|
|
contract_number='C-INSP-1',
|
|
start_date=today - timedelta(days=30),
|
|
end_date=today + timedelta(days=365)
|
|
)
|
|
|
|
self.template = OperationTemplate.objects.create(
|
|
name='GIEP Template',
|
|
thematic=self.thematic,
|
|
)
|
|
|
|
self.status_set = OperationStatusSet.objects.create(name='Default')
|
|
OperationTemplateItem.objects.create(
|
|
template=self.template,
|
|
name_fr='Inspection Item FR',
|
|
name_nl='Inspection Item NL',
|
|
status_set=self.status_set,
|
|
is_generic=True,
|
|
order=1
|
|
)
|
|
|
|
self.inspection_config = InspectionConfiguration.objects.create(
|
|
name_fr='Inspection GIEP',
|
|
name_nl='GIEP Inspectie',
|
|
description='Test description',
|
|
thematic=self.thematic,
|
|
maintain_type='preventive',
|
|
)
|
|
self.inspection_config.operation_templates.add(self.template)
|
|
|
|
from interventions.models import InspectionConfigurationContract
|
|
InspectionConfigurationContract.objects.create(
|
|
inspection_configuration=self.inspection_config,
|
|
provider=self.company,
|
|
contract=self.contract,
|
|
)
|
|
|
|
from common.models import UserContractAccess, UserContractStatusPermission
|
|
self.uca = UserContractAccess.objects.create(
|
|
user_config=self.user_config,
|
|
contract=self.contract,
|
|
can_view_interventions=True,
|
|
)
|
|
UserContractStatusPermission.objects.create(
|
|
user_contract=self.uca,
|
|
status='in_preparation',
|
|
can_change_status_to=True,
|
|
)
|
|
|
|
def test_inspection_configuration_properties(self):
|
|
from django.utils import translation
|
|
self.assertEqual(self.inspection_config.name_fr, 'Inspection GIEP')
|
|
self.assertEqual(self.inspection_config.name_nl, 'GIEP Inspectie')
|
|
|
|
# Test translation property
|
|
with translation.override('fr'):
|
|
self.assertEqual(self.inspection_config.name, 'Inspection GIEP')
|
|
with translation.override('nl'):
|
|
self.assertEqual(self.inspection_config.name, 'GIEP Inspectie')
|
|
|
|
def test_intervention_form_inspection_status_field(self):
|
|
from interventions.views.forms import InterventionForm
|
|
|
|
# When type is inspection, status field is a visible Select and defaults to to_be_processed
|
|
form = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'inspection'})
|
|
self.assertFalse(form.fields['status'].widget.is_hidden)
|
|
self.assertEqual(form.fields['status'].initial, 'to_be_processed')
|
|
self.assertEqual(list(form.fields['status'].widget.choices), list(form.fields['status'].choices))
|
|
self.assertTrue(len(form.fields['status'].widget.choices) > 0)
|
|
|
|
# When type is not inspection, status field is hidden widget and forced to in_preparation
|
|
form_normal = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'fixing'})
|
|
self.assertTrue(form_normal.fields['status'].widget.is_hidden)
|
|
self.assertEqual(form_normal.fields['status'].initial, 'in_preparation')
|
|
|
|
def test_interventions_add_get_with_inspection_config(self):
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
from django.utils import translation
|
|
with translation.override('fr'):
|
|
# GET with inspection_config_id
|
|
response = self.client.get(url, {'inspection_config_id': self.inspection_config.id})
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# Initial dictionary check in form
|
|
form = response.context['form']
|
|
self.assertEqual(form.initial.get('type'), 'inspection')
|
|
self.assertEqual(form.initial.get('status'), 'assigned')
|
|
self.assertIn('inspection - GIEP', form.initial.get('title'))
|
|
|
|
# Verify title changes
|
|
self.assertContains(response, 'inspection - GIEP')
|
|
self.assertNotContains(response, 'Créer une intervention')
|
|
|
|
def test_interventions_add_post_with_inspection_config(self):
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
from interventions.models import Symptom, AssetCategory
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
category = AssetCategory.objects.create(
|
|
code='CAT-INSP',
|
|
name_fr='Catégorie Inspection',
|
|
name_nl='Inspectiecategorie',
|
|
thematic=self.thematic
|
|
)
|
|
|
|
symptom = Symptom.objects.create(
|
|
code='SYMP-INSP',
|
|
name_fr='Symptôme Inspection',
|
|
name_nl='Inspectiesymptoom',
|
|
thematic=self.thematic
|
|
)
|
|
|
|
from assets.models import Structure, StructureLocation
|
|
structure = Structure.objects.create(code='OA001')
|
|
location_obj = StructureLocation.objects.create(code='LOC001', structure=structure)
|
|
location_ct = ContentType.objects.get_for_model(StructureLocation)
|
|
|
|
# Standard post parameters
|
|
post_data = {
|
|
'title': 'Nouvelle Inspection GIEP',
|
|
'type': 'inspection',
|
|
'status': 'to_be_processed',
|
|
'symptom': symptom.id,
|
|
'asset_category': category.id,
|
|
'maintain_type': 'preventive',
|
|
'inspection_config_id': self.inspection_config.id,
|
|
'lon': '4.35',
|
|
'lat': '50.85',
|
|
'location_ct': location_ct.id,
|
|
'location_id': location_obj.id,
|
|
'priority': '3',
|
|
'origin_type': 'demand',
|
|
}
|
|
|
|
response = self.client.post(url, data=post_data)
|
|
# If successfully created, it should redirect to intervention detail
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
# Retrieve the created intervention
|
|
from interventions.models import Intervention, Operation
|
|
intervention = Intervention.objects.get(title='Nouvelle Inspection GIEP')
|
|
|
|
# Check field values
|
|
self.assertEqual(intervention.type, 'inspection')
|
|
self.assertEqual(intervention.status, 'to_be_processed')
|
|
# Should auto-assign contract & provider from configuration
|
|
self.assertEqual(intervention.contract, self.contract)
|
|
self.assertEqual(intervention.assigned_provider, self.company)
|
|
|
|
# Check generic operation from template is created
|
|
operations = Operation.objects.filter(intervention=intervention)
|
|
self.assertTrue(operations.exists())
|
|
self.assertEqual(operations.first().name_fr, 'Inspection Item FR')
|
|
|
|
def test_homepage_filters_configurations_by_transition_rights(self):
|
|
from common.models import UserConfig, Role
|
|
from contracts.models import Company, Contract
|
|
from interventions.models import InspectionConfiguration, InspectionConfigurationContract
|
|
|
|
# 1. Create a second configuration that the user has NO rights on
|
|
company_2 = Company.objects.create(name='Provider B')
|
|
contract_2 = Contract.objects.create(
|
|
company=company_2,
|
|
contract_number='C-INSP-2',
|
|
start_date=timezone.now().date() - timedelta(days=30),
|
|
end_date=timezone.now().date() + timedelta(days=365)
|
|
)
|
|
inspection_config_2 = InspectionConfiguration.objects.create(
|
|
name_fr='Inspection OA',
|
|
name_nl='OA Inspectie',
|
|
description='Second config description',
|
|
thematic=self.thematic,
|
|
maintain_type='preventive',
|
|
)
|
|
InspectionConfigurationContract.objects.create(
|
|
inspection_configuration=inspection_config_2,
|
|
provider=company_2,
|
|
contract=contract_2,
|
|
)
|
|
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
response = self.client.get(reverse('home:index'))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# The user has rights on self.contract (self.inspection_config), so it should be visible
|
|
self.assertIn(self.inspection_config, response.context['inspection_configs'])
|
|
# The user has NO rights on contract_2 (inspection_config_2), so it should NOT be visible
|
|
self.assertNotIn(inspection_config_2, response.context['inspection_configs'])
|
|
|
|
def test_interventions_add_get_forbidden_if_no_transition_rights(self):
|
|
# Create an inspector with NO rights on self.contract
|
|
User = get_user_model()
|
|
unauthorized_user = User.objects.create_user(username='unauthorized_inspector', password='pwd')
|
|
unauthorized_config = UserConfig.objects.create(user=unauthorized_user, is_intern=True)
|
|
unauthorized_config.roles.add(self.role_inspector)
|
|
|
|
from common.models import UserThematics
|
|
UserThematics.objects.create(
|
|
user_config=unauthorized_config,
|
|
thematic=self.thematic,
|
|
can_view_interventions=True,
|
|
can_edit_interventions=True,
|
|
)
|
|
|
|
self.client.login(username='unauthorized_inspector', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
response = self.client.get(url, {'inspection_config_id': self.inspection_config.id})
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_interventions_add_post_forbidden_if_no_transition_rights(self):
|
|
# Create an inspector with NO rights on self.contract
|
|
User = get_user_model()
|
|
unauthorized_user = User.objects.create_user(username='unauthorized_inspector_2', password='pwd')
|
|
unauthorized_config = UserConfig.objects.create(user=unauthorized_user, is_intern=True)
|
|
unauthorized_config.roles.add(self.role_inspector)
|
|
|
|
from common.models import UserThematics
|
|
UserThematics.objects.create(
|
|
user_config=unauthorized_config,
|
|
thematic=self.thematic,
|
|
can_view_interventions=True,
|
|
can_edit_interventions=True,
|
|
)
|
|
|
|
self.client.login(username='unauthorized_inspector_2', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
post_data = {
|
|
'title': 'Nouvelle Inspection GIEP 2',
|
|
'type': 'inspection',
|
|
'status': 'to_be_processed',
|
|
'maintain_type': 'preventive',
|
|
'inspection_config_id': self.inspection_config.id,
|
|
'lon': '4.35',
|
|
'lat': '50.85',
|
|
'priority': '3',
|
|
'origin_type': 'demand',
|
|
}
|
|
response = self.client.post(url, data=post_data)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_interventions_add_post_with_multiple_contracts_resolution(self):
|
|
from contracts.models import Company, Contract
|
|
from interventions.models import InspectionConfigurationContract
|
|
from common.models import UserContractAccess, UserContractStatusPermission
|
|
|
|
# Add a second allowed contract-provider couple to the configuration
|
|
company_2 = Company.objects.create(name='Provider B')
|
|
contract_2 = Contract.objects.create(
|
|
company=company_2,
|
|
contract_number='C-INSP-2',
|
|
start_date=timezone.now().date() - timedelta(days=30),
|
|
end_date=timezone.now().date() + timedelta(days=365)
|
|
)
|
|
|
|
# Associate with config
|
|
InspectionConfigurationContract.objects.create(
|
|
inspection_configuration=self.inspection_config,
|
|
provider=company_2,
|
|
contract=contract_2,
|
|
)
|
|
|
|
# Give status transition permissions to the inspector for contract_2 as well
|
|
uca_2 = UserContractAccess.objects.create(
|
|
user_config=self.user_config,
|
|
contract=contract_2,
|
|
can_view_interventions=True,
|
|
)
|
|
UserContractStatusPermission.objects.create(
|
|
user_contract=uca_2,
|
|
status='in_preparation',
|
|
can_change_status_to=True,
|
|
)
|
|
|
|
# Let's perform a post
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
from interventions.models import Symptom, AssetCategory
|
|
category = AssetCategory.objects.create(
|
|
code='CAT-INSP-2',
|
|
name_fr='Catégorie 2',
|
|
name_nl='Categorie 2',
|
|
thematic=self.thematic
|
|
)
|
|
symptom = Symptom.objects.create(
|
|
code='SYMP-INSP-2',
|
|
name_fr='Symptôme 2',
|
|
name_nl='Symptoom 2',
|
|
thematic=self.thematic
|
|
)
|
|
|
|
post_data = {
|
|
'title': 'Multiple Contracts Inspection',
|
|
'type': 'inspection',
|
|
'status': 'to_be_processed',
|
|
'symptom': symptom.id,
|
|
'asset_category': category.id,
|
|
'maintain_type': 'preventive',
|
|
'inspection_config_id': self.inspection_config.id,
|
|
'lon': '4.35',
|
|
'lat': '50.85',
|
|
'priority': '3',
|
|
'origin_type': 'demand',
|
|
}
|
|
response = self.client.post(url, data=post_data)
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
from interventions.models import Intervention
|
|
intervention = Intervention.objects.get(title='Multiple Contracts Inspection')
|
|
# Since we didn't match any specific contract via location or other means,
|
|
# it should fall back to the first allowed couple in the list
|
|
self.assertIn(intervention.contract, [self.contract, contract_2])
|
|
self.assertIn(intervention.assigned_provider, [self.company, company_2])
|
|
|
|
def test_interventions_add_get_with_inspection_config_default_category(self):
|
|
from assets.models import AssetCategory
|
|
category = AssetCategory.objects.create(
|
|
code='CAT-DFLT',
|
|
name_fr='Catégorie Par Défaut',
|
|
name_nl='Standaardcategorie',
|
|
thematic=self.thematic
|
|
)
|
|
self.inspection_config.default_category = category
|
|
self.inspection_config.save()
|
|
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
response = self.client.get(url, {'inspection_config_id': self.inspection_config.id})
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
form = response.context['form']
|
|
self.assertEqual(form.initial.get('asset_category'), category.id)
|
|
|
|
def test_interventions_add_get_with_inspection_config_default_subcategory(self):
|
|
from assets.models import AssetCategory
|
|
parent_category = AssetCategory.objects.create(
|
|
code='CAT-PARENT',
|
|
name_fr='Catégorie Parente',
|
|
name_nl='Oudercategorie',
|
|
thematic=self.thematic
|
|
)
|
|
child_category = AssetCategory.objects.create(
|
|
code='CAT-CHILD',
|
|
name_fr='Catégorie Enfant',
|
|
name_nl='Kindcategorie',
|
|
thematic=self.thematic,
|
|
parent=parent_category
|
|
)
|
|
self.inspection_config.default_category = child_category
|
|
self.inspection_config.save()
|
|
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:intervention_add', kwargs={'thematic_code': self.thematic.code})
|
|
|
|
response = self.client.get(url, {'inspection_config_id': self.inspection_config.id})
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
form = response.context['form']
|
|
# The parent category should be pre-filled in the asset_category field
|
|
self.assertEqual(form.initial.get('asset_category'), parent_category.id)
|
|
# The child category should be pre-filled in the hidden/initial interv_sub_category_id variable
|
|
self.assertEqual(response.context['initial_interv_sub_category_id'], str(child_category.id))
|
|
# The subcategory dropdown should contain the child category as selected
|
|
initial_subcategories = response.context['initial_subcategories']
|
|
self.assertTrue(any(sub['id'] == child_category.id and sub['selected'] for sub in initial_subcategories))
|
|
|
|
def test_inspection_configuration_geojson(self):
|
|
from assets.models import Structure, StructureLocation
|
|
from django.contrib.contenttypes.models import ContentType
|
|
import json
|
|
|
|
structure = Structure.objects.create(code='OA999')
|
|
location_obj = StructureLocation.objects.create(
|
|
code='LOC999',
|
|
structure=structure,
|
|
lon=4.40,
|
|
lat=50.90,
|
|
geojson=json.dumps({
|
|
"type": "Polygon",
|
|
"coordinates": [[[4.40, 50.90], [4.41, 50.90], [4.41, 50.91], [4.40, 50.91], [4.40, 50.90]]]
|
|
})
|
|
)
|
|
location_ct = ContentType.objects.get_for_model(StructureLocation)
|
|
|
|
# Link the location ContentType class to the displayed location types ManyToMany
|
|
self.inspection_config.displayed_location_types.add(location_ct)
|
|
|
|
self.client.login(username='inspector_user', password='pwd')
|
|
url = reverse('interventions:inspection_configuration_geojson', kwargs={'config_id': self.inspection_config.id})
|
|
|
|
response = self.client.get(url)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
geojson_data = response.json()
|
|
self.assertEqual(geojson_data['type'], 'FeatureCollection')
|
|
self.assertEqual(len(geojson_data['features']), 1)
|
|
|
|
feature = geojson_data['features'][0]
|
|
self.assertEqual(feature['properties']['type'], 'location')
|
|
self.assertEqual(feature['properties']['id'], location_obj.id)
|
|
self.assertEqual(feature['properties']['code'], 'LOC999')
|
|
self.assertIn(feature['geometry']['type'], ['Polygon', 'Point'])
|
|
|
|
def test_inspector_can_edit_inspection_with_permissions(self):
|
|
from interventions.permissions import can_edit_intervention
|
|
from common.models import UserContractStatusPermission
|
|
UserContractStatusPermission.objects.filter(
|
|
user_contract=self.uca,
|
|
status='in_preparation'
|
|
).update(can_edit=True)
|
|
|
|
intervention = Intervention.objects.create(
|
|
title='Inspection Test Edit',
|
|
type='inspection',
|
|
contract=self.contract,
|
|
thematic=self.thematic,
|
|
status='in_preparation',
|
|
)
|
|
self.assertTrue(can_edit_intervention(self.user, intervention))
|
|
|
|
def test_inspector_cannot_edit_inspection_without_permissions(self):
|
|
from interventions.permissions import can_edit_intervention
|
|
unauthorized_user = get_user_model().objects.create_user(username='unauthorized_inspector_edit', password='pwd')
|
|
unauthorized_config = UserConfig.objects.create(user=unauthorized_user, is_intern=True)
|
|
unauthorized_config.roles.add(self.role_inspector)
|
|
|
|
intervention = Intervention.objects.create(
|
|
title='Inspection Test Edit Forbidden',
|
|
type='inspection',
|
|
contract=self.contract,
|
|
thematic=self.thematic,
|
|
status='in_preparation',
|
|
)
|
|
self.assertFalse(can_edit_intervention(unauthorized_user, intervention))
|
|
|
|
def test_inspector_cannot_edit_non_inspection_intervention(self):
|
|
from interventions.permissions import can_edit_intervention
|
|
from common.models import UserContractStatusPermission
|
|
UserContractStatusPermission.objects.filter(
|
|
user_contract=self.uca,
|
|
status='in_preparation'
|
|
).update(can_edit=True)
|
|
|
|
intervention = Intervention.objects.create(
|
|
title='Fixing Test Edit Forbidden',
|
|
type='fixing',
|
|
contract=self.contract,
|
|
thematic=self.thematic,
|
|
status='in_preparation',
|
|
)
|
|
self.assertFalse(can_edit_intervention(self.user, intervention))
|
|
|
|
def test_inspector_bypasses_technician_assignment_for_inspections(self):
|
|
from interventions.permissions import can_edit_intervention
|
|
from common.models import Role, UserContractStatusPermission
|
|
UserContractStatusPermission.objects.filter(
|
|
user_contract=self.uca,
|
|
status='in_preparation'
|
|
).update(can_edit=True)
|
|
|
|
role_technician, _ = Role.objects.get_or_create(name='technician')
|
|
self.user_config.roles.add(role_technician)
|
|
|
|
assigned_user = get_user_model().objects.create_user(username='other_tech', password='pwd')
|
|
assigned_member = CompanyMember.objects.create(user=assigned_user, name='Other Tech')
|
|
|
|
intervention = Intervention.objects.create(
|
|
title='Inspection Assigned to Other Tech',
|
|
type='inspection',
|
|
contract=self.contract,
|
|
thematic=self.thematic,
|
|
status='in_preparation',
|
|
assigned_member=assigned_member,
|
|
)
|
|
|
|
self.assertTrue(can_edit_intervention(self.user, intervention))
|
|
|
|
def test_inspector_allowed_update_fields(self):
|
|
from interventions.permissions import get_allowed_update_fields
|
|
from common.models import UserContractStatusPermission
|
|
UserContractStatusPermission.objects.filter(
|
|
user_contract=self.uca,
|
|
status='in_preparation'
|
|
).update(can_edit=True)
|
|
|
|
intervention = Intervention.objects.create(
|
|
title='Inspection Fields Test',
|
|
type='inspection',
|
|
contract=self.contract,
|
|
thematic=self.thematic,
|
|
status='in_preparation',
|
|
)
|
|
allowed_fields = get_allowed_update_fields(self.user, intervention)
|
|
self.assertIn('operations', allowed_fields)
|
|
self.assertIn('realization', allowed_fields)
|
|
self.assertIn('planification', allowed_fields)
|
|
self.assertIn('title', allowed_fields)
|
|
self.assertIn('member_assignment', allowed_fields)
|
|
|
|
|
|
class InterventionSubTypeTests(TestCase):
|
|
def setUp(self):
|
|
User = get_user_model()
|
|
self.user = User.objects.create_user(username='subtype_test_user', password='pwd')
|
|
self.thematic = Thematic.objects.create(code='roads_test', name_fr='Voirie Test', name_nl='Wegen Test')
|
|
self.company = Company.objects.create(name='Test Contractor')
|
|
self.team1 = CompanyTeam.objects.create(name='Équipe Régie 1', company=self.company)
|
|
self.team2 = CompanyTeam.objects.create(name='Équipe Prestataire 2', company=self.company)
|
|
|
|
from interventions.models import InterventionSubType
|
|
self.subtype_multi = InterventionSubType.objects.create(
|
|
code='sub_multi',
|
|
name_fr='Hot Box Multi',
|
|
name_nl='Hot Box NL',
|
|
thematic=self.thematic,
|
|
intervention_types=['repair', 'fixing'],
|
|
requires_post_inspection=True,
|
|
order_number=1,
|
|
is_active=True,
|
|
)
|
|
self.subtype_multi.notification_teams.add(self.team1, self.team2)
|
|
|
|
self.subtype_universal = InterventionSubType.objects.create(
|
|
code='sub_univ',
|
|
name_fr='Universel',
|
|
name_nl='Universeel',
|
|
thematic=self.thematic,
|
|
intervention_types=[],
|
|
requires_post_inspection=False,
|
|
order_number=2,
|
|
is_active=True,
|
|
)
|
|
|
|
self.subtype_build_only = InterventionSubType.objects.create(
|
|
code='sub_build',
|
|
name_fr='Construction Seule',
|
|
thematic=self.thematic,
|
|
intervention_types=['build'],
|
|
order_number=3,
|
|
is_active=True,
|
|
)
|
|
|
|
def test_subtype_multiple_types_and_teams(self):
|
|
from interventions.models import InterventionSubType
|
|
st = InterventionSubType.objects.get(code='sub_multi')
|
|
self.assertEqual(st.intervention_types, ['repair', 'fixing'])
|
|
self.assertEqual(st.notification_teams.count(), 2)
|
|
self.assertIn(self.team1, st.notification_teams.all())
|
|
self.assertIn(self.team2, st.notification_teams.all())
|
|
|
|
def test_form_filters_subtypes_by_type(self):
|
|
from interventions.views.forms import InterventionForm
|
|
# Form for 'repair' should include sub_multi and sub_univ, but NOT sub_build
|
|
form_repair = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'repair'})
|
|
qs_repair = form_repair.fields['sub_type'].queryset
|
|
self.assertIn(self.subtype_multi, qs_repair)
|
|
self.assertIn(self.subtype_universal, qs_repair)
|
|
self.assertNotIn(self.subtype_build_only, qs_repair)
|
|
|
|
# Form for 'build' should include sub_build and sub_univ, but NOT sub_multi
|
|
form_build = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'build'})
|
|
qs_build = form_build.fields['sub_type'].queryset
|
|
self.assertIn(self.subtype_build_only, qs_build)
|
|
self.assertIn(self.subtype_universal, qs_build)
|
|
self.assertNotIn(self.subtype_multi, qs_build)
|
|
|
|
def test_admin_types_display(self):
|
|
from interventions.admin import InterventionSubTypeAdmin
|
|
from django.contrib.admin.sites import AdminSite
|
|
from django.utils import translation
|
|
admin_instance = InterventionSubTypeAdmin(self.subtype_multi.__class__, AdminSite())
|
|
with translation.override('fr'):
|
|
display_text = admin_instance.types_display(self.subtype_multi)
|
|
self.assertIn("Réparation", display_text)
|
|
self.assertIn("Dépannage", display_text)
|
|
|
|
display_univ = admin_instance.types_display(self.subtype_universal)
|
|
self.assertEqual(str(display_univ), "Tous")
|
|
|
|
|
|
|
|
|
|
|