157 lines
6 KiB
Python
157 lines
6 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 MobileInterventionAssetsApiTests(TestCase):
|
|
def setUp(self):
|
|
self.User = get_user_model()
|
|
self.user = self.User.objects.create_user(username='mobile-admin', password='pwd')
|
|
self.role_admin = Role.objects.create(name='admin')
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
self.user_config.roles.add(self.role_admin)
|
|
|
|
self.thematic = Thematic.objects.create(code='road', name_fr='Route', name_nl='Weg')
|
|
self.category = AssetCategory.objects.create(
|
|
code='CAT1',
|
|
name_fr='Catégorie 1',
|
|
name_nl='Categorie 1',
|
|
thematic=self.thematic,
|
|
)
|
|
self.intervention = Intervention.objects.create(
|
|
title='Mobile assets',
|
|
status='to_be_processed',
|
|
thematic=self.thematic,
|
|
)
|
|
|
|
self.filters_url = reverse('interventions:mobile_intervention_assets_filters', args=[self.intervention.id])
|
|
self.search_url = reverse('interventions:mobile_intervention_assets_search', args=[self.intervention.id])
|
|
self.sync_url = reverse('interventions:mobile_intervention_assets_sync', args=[self.intervention.id])
|
|
|
|
self.client.login(username='mobile-admin', password='pwd')
|
|
|
|
def test_filters_endpoint_returns_categories(self):
|
|
with mock.patch('interventions.views._get_asset_model_classes', return_value=[]):
|
|
response = self.client.get(self.filters_url)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
payload = response.json()
|
|
self.assertTrue(payload.get('success'))
|
|
self.assertEqual(len(payload.get('categories', [])), 1)
|
|
self.assertEqual(payload['categories'][0]['id'], self.category.id)
|
|
|
|
def test_search_endpoint_wraps_helper(self):
|
|
fake_results = {
|
|
'assets': [],
|
|
'match_count': 0,
|
|
'has_more': False,
|
|
'requires_category': False,
|
|
'has_locations': False,
|
|
}
|
|
|
|
with mock.patch('interventions.views._search_mobile_assets', return_value=fake_results) as mocked:
|
|
response = self.client.get(self.search_url, {'q': 'lamp'})
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertTrue(response.json().get('success'))
|
|
self.assertEqual(response.json().get('results'), fake_results)
|
|
mocked.assert_called_once()
|
|
|
|
def test_sync_endpoint_returns_stats(self):
|
|
stats = {
|
|
'created': 1,
|
|
'deleted': 0,
|
|
'operations_created': 0,
|
|
'operations_deleted': 0,
|
|
'assets_with_values': 0,
|
|
'target_total': 1,
|
|
'requested_assets': 1,
|
|
}
|
|
|
|
with mock.patch('interventions.views._sync_intervention_assets_data', return_value=stats) as mocked:
|
|
response = self.client.post(
|
|
self.sync_url,
|
|
data=json.dumps({'assets': [{'model': 'signstreet', 'object_id': 42}]}),
|
|
content_type='application/json',
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
payload = response.json()
|
|
self.assertTrue(payload.get('success'))
|
|
self.assertEqual(payload.get('stats'), stats)
|
|
mocked.assert_called_once()
|
|
|
|
|
|
|
|
|
|
class MobileInterventionPauseTests(TestCase):
|
|
def setUp(self):
|
|
User = get_user_model()
|
|
self.user = User.objects.create_user(username='mobileuser', password='pwd')
|
|
# Give admin role to bypass permissions
|
|
self.role_admin = Role.objects.create(name='admin')
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
self.user_config.roles.add(self.role_admin)
|
|
|
|
# Create an intervention in progress
|
|
self.intervention = Intervention.objects.create(title='Mobile Pause', status='in_progress')
|
|
|
|
# Optional: link a company member to the user
|
|
self.company = Company.objects.create(name='MobileCo')
|
|
self.team = CompanyTeam.objects.create(name='Team M', company=self.company)
|
|
self.member = CompanyMember.objects.create(user=self.user, name='Mobile User')
|
|
self.member.teams.add(self.team)
|
|
|
|
def test_pause_reason_is_persisted_from_mobile_detail(self):
|
|
self.client.login(username='mobileuser', password='pwd')
|
|
url = reverse('mobile:intervention_detail_mobile', args=[self.intervention.id])
|
|
|
|
resp = self.client.post(url, {
|
|
'status_action': 'pause',
|
|
'pause_reason': 'other',
|
|
'pause_reason_other': 'Pluie abondante',
|
|
})
|
|
|
|
# Redirect back to detail
|
|
self.assertEqual(resp.status_code, 302)
|
|
|
|
# Verify persisted values
|
|
self.intervention.refresh_from_db()
|
|
self.assertEqual(self.intervention.status, 'on_pause')
|
|
self.assertEqual(self.intervention.pause_reason, 'other')
|
|
self.assertEqual(self.intervention.pause_reason_other, 'Pluie abondante')
|
|
|
|
|
|
|
|
|