from datetime import timedelta from unittest import mock from django.utils import timezone from rest_framework.test import APITestCase from api.models import User from vehicles.models import Vehicle STATION = {'station_key': 'test-station'} class OneWeightTests(APITestCase): def setUp(self): self.user = User.objects.create_user('op', password='x', can_measure=True) self.other = User.objects.create_user('first', password='x') self.client.force_authenticate(self.user) p = mock.patch('api.views._station_allowed', return_value=True) p.start() self.addCleanup(p.stop) p = mock.patch('api.views.sse_broadcast_update') self.sse = p.start() self.addCleanup(p.stop) def url(self, v): return f'/api/vehicles/{v.pk}/one-weight/' def make(self, **kw): return Vehicle.objects.create(vehicle_number='CB1234', driver_name='D', **kw) def test_moves_tare_to_gross_and_finalizes(self): when = timezone.now() - timedelta(hours=1) v = self.make(tare=1500, tare_date=when, tare_user=self.other, tare_manual=True, tare_manual_user=self.other, tare_manual_date=when, tare_manual_note='n') r = self.client.post(self.url(v), STATION, format='json') self.assertEqual(r.status_code, 200, r.content) v.refresh_from_db() self.assertEqual(v.gross, 1500) self.assertEqual(v.gross_date, when) self.assertEqual(v.gross_user, self.other) self.assertTrue(v.gross_manual) self.assertEqual(v.gross_manual_user, self.other) self.assertEqual(v.gross_manual_date, when) self.assertEqual(v.gross_manual_note, 'n') for f in ('tare', 'tare_date', 'tare_user', 'tare_manual_user', 'tare_manual_date', 'tare_manual_note'): self.assertIsNone(getattr(v, f), f) self.assertFalse(v.tare_manual) self.assertEqual(v.net, 1500) self.assertEqual(v.net_user, self.user) self.assertIsNotNone(v.net_date) self.assertTrue(v.doc_number) self.assertEqual(r.data['doc_number'], v.doc_number) self.assertEqual(r.data['net'], 1500) self.assertIsNone(r.data['tare']) self.sse.assert_called_once() self.assertEqual(self.sse.call_args.args[:2], ('vehicle', 'updated')) def test_gross_already_set(self): when = timezone.now() v = self.make(gross=9000, gross_date=when, gross_user=self.other) r = self.client.post(self.url(v), STATION, format='json') self.assertEqual(r.status_code, 200, r.content) v.refresh_from_db() self.assertEqual((v.gross, v.gross_user, v.gross_date), (9000, self.other, when)) self.assertIsNone(v.tare) self.assertEqual(v.net, 9000) self.assertTrue(v.doc_number) def _assert_400(self, v): r = self.client.post(self.url(v), STATION, format='json') self.assertEqual(r.status_code, 400) self.assertIn('detail', r.data) self.sse.assert_not_called() def test_already_finalized(self): self._assert_400(self.make(gross=5, net=5, doc_number='2026-1')) def test_void(self): self._assert_400(self.make(tare=5, is_void=True)) def test_no_weight(self): self._assert_400(self.make()) def test_both_weights(self): self._assert_400(self.make(tare=5, gross=10)) def test_permission_denied(self): v = self.make(tare=5) self.client.force_authenticate(self.other) r = self.client.post(self.url(v), STATION, format='json') self.assertEqual(r.status_code, 403) v.refresh_from_db() self.assertEqual(v.tare, 5) self.assertIsNone(v.doc_number) def test_station_not_licensed(self): v = self.make(tare=5) with mock.patch('api.views._station_allowed', return_value=False): r = self.client.post(self.url(v), STATION, format='json') self.assertEqual(r.status_code, 403) def test_unknown_vehicle_404(self): r = self.client.post('/api/vehicles/999999/one-weight/', STATION, format='json') self.assertEqual(r.status_code, 404)