def test_only_main_category_filter(self): """ unit test to only filter items with the main category create 5 signals and only 3 under the main category 'trash' that should be returned """ parent_cat = ParentCategoryFactory.create(name='trash') child_category = CategoryFactory.create(parent=parent_cat, public_name='', is_public_accessible=True) child_category_2 = CategoryFactory.create(parent=parent_cat, public_name='', is_public_accessible=True) SignalFactoryValidLocation.create( category_assignment__category=child_category) SignalFactoryValidLocation.create( category_assignment__category=child_category) SignalFactoryValidLocation.create( category_assignment__category=child_category_2) parent_cat_2 = ParentCategoryFactory.create(name='animal') child_animal = CategoryFactory.create(parent=parent_cat_2, public_name='', is_public_accessible=True) SignalFactoryValidLocation.create( category_assignment__category=child_animal) SignalFactoryValidLocation.create( category_assignment__category=child_animal) response = self.client.get( f'{self.geography_endpoint}/?bbox=4.700000,52.200000,5.000000,52.500000&' f'maincategory_slug={parent_cat.slug}') data = response.json() self.assertEqual(3, len(data['features']))
def test_public_name_isset(self): """ An empty public_name (None) must fallback to the name """ parent_category = ParentCategoryFactory.create() child_category = CategoryFactory.create(parent=parent_category, public_name='test', is_public_accessible=True) SignalFactoryValidLocation.create( category_assignment__category=child_category) response = self.client.get( f'{self.geography_endpoint}/?maincategory_slug={parent_category.slug}' f'&category_slug={child_category.slug}&bbox=4.700000,52.200000,5.000000,52.500000' ) self.assertEqual(200, response.status_code) self.assertEqual(1, int(response.headers['X-Total-Count'])) data = response.json() self.assertEqual(1, len(data['features'])) self.assertEqual(child_category.public_name, data['features'][0]['properties']['category']['name']) self.assertNotEqual( child_category.name, data['features'][0]['properties']['category']['name'])
def test_get_geojson(self): """ Return the GEOJson containing all signals in the child category """ parent_category = ParentCategoryFactory.create() child_category = CategoryFactory.create( parent=parent_category, public_name='Public category for testing', is_public_accessible=True) now = timezone.now() for x in range(5): with (freeze_time(now - timedelta(days=x))): SignalFactoryValidLocation.create( category_assignment__category=child_category) response = self.client.get( f'{self.geography_endpoint}/?maincategory_slug={parent_category.slug}' f'&category_slug={child_category.slug}&bbox=4.700000,52.200000,5.000000,52.500000' ) self.assertEqual(200, response.status_code) self.assertEqual(5, int(response.headers['X-Total-Count'])) data = response.json() self.assertEqual(5, len(data['features'])) for feature in data['features']: self.assertEqual(feature['properties']['category']['name'], child_category.public_name)
def test_handling_message_in_history_is_constant(self): # SIG-3555 because history is not tracked for the Category model and its # handling_message. Changing the handling_message will also change the # history of every Signal that has that Category associated with. # This test demonstrates the problem. message_1 = 'MESSAGE 1' message_2 = 'MESSAGE 2' cat1 = CategoryFactory.create(name='cat1', handling_message=message_1) cat2 = CategoryFactory.create(name='cat2') signal = SignalFactoryValidLocation(category_assignment__category=cat1) self.sia_read_write_user.user_permissions.add( Permission.objects.get(codename='sia_can_view_all_categories')) self.client.force_authenticate(user=self.sia_read_write_user) # Retrieve signal history before changing the Category handling message. response = self.client.get( f'/signals/v1/private/signals/{signal.id}/history' + '?what=UPDATE_SLA') self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(len(response_json), 1) self.assertEqual(response_json[0]['description'], message_1) # Change handling message on category cat1.handling_message = message_2 cat1.save() cat1.refresh_from_db() # Assign different category and then the same again, check handling messages. Signal.actions.update_category_assignment({'category': cat2}, signal) signal.refresh_from_db() Signal.actions.update_category_assignment({'category': cat1}, signal) response = self.client.get( f'/signals/v1/private/signals/{signal.id}/history' + '?what=UPDATE_SLA') self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(len(response_json), 1) self.assertEqual(response_json[0]['description'], message_1) # check that the correct handling messages are stored: category_assignments = list( CategoryAssignment.objects.filter( _signal_id=signal.id).order_by('id')) self.assertEqual(category_assignments[0].stored_handling_message, message_1) self.assertEqual(category_assignments[2].stored_handling_message, message_2)
def test_with_signal_for_message_wrong_state(self): signal = SignalFactoryValidLocation.create() self.assertEqual(Signal.objects.count(), 1) incoming_msg = render_to_string('sigmax/actualiseerZaakstatus_Lk01.xml', { 'signal': signal, 'tijdstipbericht': '20180927100000', 'resultaat_omschrijving': 'HALLO', }) # authenticate self.client.force_authenticate(user=self.superuser) # call our SOAP endpoint response = self.client.post( SOAP_ENDPOINT, data=incoming_msg, HTTP_SOAPACTION=ACTUALISEER_ZAAK_STATUS, content_type='text/xml', ) self.assertEqual(response.status_code, 500) self.assertIn(str(signal.sia_id), response.content.decode('utf-8', 'strict')) self.assertIn('Fo03', response.content.decode('utf-8', 'strict')) last_update = History.objects.filter(_signal__id=signal.pk).order_by('-when').first() self.assertEqual(last_update.what, 'CREATE_NOTE') self.assertTrue(last_update.description.startswith( 'Zaak status update ontvangen van CityControl terwijl SIA melding niet in verzonden staat was.')) # noqa
def test_lon_lat_parameters(self): """ Return the GEOJson containing all signals in the child category """ parent_category = ParentCategoryFactory.create() child_category = CategoryFactory.create( parent=parent_category, public_name='Public category for testing', is_public_accessible=True) signal = SignalFactoryValidLocation.create( category_assignment__category=child_category) lon = signal.location.geometrie.x lat = signal.location.geometrie.y response = self.client.get( f'{self.geography_endpoint}/?maincategory_slug={parent_category.slug}' f'&category_slug={child_category.slug}&lon={lon}&lat={lat}') self.assertEqual(200, response.status_code) self.assertEqual(1, int(response.headers['X-Total-Count'])) data = response.json() self.assertEqual(1, len(data['features'])) for feature in data['features']: self.assertEqual(feature['properties']['category']['name'], child_category.public_name)
def setUp(self): # Times for various actions (assumes a 14 day window for feedback). self.t_now = '2019-04-01 12:00:00' self.t_creation = '2019-03-01 12:00:00' self.t_expired = '2019-03-02 12:00:00' self.t_received = '2019-03-29 12:00:00' # Setup our test signal and feedback instances with freeze_time(self.t_creation): self.reporter = ReporterFactory() self.signal = SignalFactoryValidLocation( reporter=self.reporter, status__state=workflow.AFGEHANDELD, ) with freeze_time(self.t_now): self.feedback = FeedbackFactory( submitted_at=None, _signal=self.signal, ) with freeze_time(self.t_expired): self.feedback_expired = FeedbackFactory( submitted_at=None, _signal=self.signal, ) with freeze_time(self.t_received): self.feedback_received = FeedbackFactory( submitted_at=timezone.now() - timedelta(days=5), _signal=self.signal, ) # Setup a standard answer that triggers a request to reopen. self.sa_reopens = StandardAnswerFactory.create( text='Ik ben niet blij met de afhandeling, duurde te lang.', is_satisfied=False, reopens_when_unhappy=True, ) self.sa_no_sideeffect = StandardAnswerFactory.create( text='Ik ben niet blij. Blah, blah.', is_satisfied=False, reopens_when_unhappy=False, )
def setUp(self): self.signal = SignalFactoryValidLocation() self.feedback = FeedbackFactory( _signal=self.signal, is_satisfied=None, ) self.feedback_endpoint = '/signals/v1/public/feedback/forms/{token}' self.history_endpoint = '/signals/v1/private/signals/{id}/history'
def test_generate_voegZaakdocumentToe_Lk01(self): signal = SignalFactoryValidLocation.create() seq_no = _generate_sequence_number(signal) xml_message = _generate_voegZaakdocumentToe_Lk01(signal, seq_no) self.assertXmlDocument(xml_message) self.assertIn( f'<ZKN:identificatie>{signal.sia_id}.{seq_no}</ZKN:identificatie>', xml_message)
def test_get_geojson_no_signals_in_category(self): """ Return an empty FeatureCollection because there are no signals in the category """ parent_category = ParentCategoryFactory.create() child_category = CategoryFactory.create( parent=parent_category, public_name='Public category for testing', is_public_accessible=True) SignalFactoryValidLocation.create_batch(5) response = self.client.get( f'{self.geography_endpoint}/?maincategory_slug={parent_category.slug}' f'&category_slug={child_category.slug}&bbox=4.700000,52.200000,5.000000,52.500000' ) self.assertEqual(200, response.status_code) self.assertEqual(0, int(response.headers['X-Total-Count'])) data = response.json() self.assertIsNone(data['features'])
def test_only_category_filter(self): """ unit test to only filter items with the category create 3 signals and only 2 signals with the category 'plastic_trash" """ cat1 = ParentCategoryFactory.create(name='trash') plastic = CategoryFactory.create(parent=cat1, public_name='plastic_trash', is_public_accessible=True) compost = CategoryFactory.create(parent=cat1, public_name='compost_trash', is_public_accessible=True) SignalFactoryValidLocation.create( category_assignment__category=plastic) SignalFactoryValidLocation.create( category_assignment__category=plastic) SignalFactoryValidLocation.create( category_assignment__category=compost) response = self.client.get( f'{self.geography_endpoint}/?bbox=4.700000,52.200000,5.000000,52.500000&' f'category_slug={plastic.slug}') data = response.json() self.assertEqual(2, len(data['features']))
def test_with_signal_for_message_correct_state_no_resultaat_toelichting( self): signal = SignalFactoryValidLocation.create() signal.status.state = workflow.VERZONDEN signal.status.save() signal.refresh_from_db() self.assertEqual(Signal.objects.count(), 1) incoming_context = { 'signal': signal, 'tijdstipbericht': '20180927100000', 'resultaat_omschrijving': 'Op locatie geweest, niets aangetroffen', 'resultaat_toelichting': '', # is translated to 'reden' upon reception 'resultaat_datum': '2018101111485276', } incoming_msg = render_to_string( 'sigmax/actualiseerZaakstatus_Lk01.xml', incoming_context) # authenticate self.client.force_authenticate(user=self.superuser) # call our SOAP endpoint response = self.client.post( SOAP_ENDPOINT, data=incoming_msg, HTTP_SOAPACTION=ACTUALISEER_ZAAK_STATUS, content_type='text/xml', ) self.assertEqual(response.status_code, 200) self.assertIn(str(signal.sia_id), response.content.decode('utf-8', 'strict')) self.assertIn('Bv03', response.content.decode('utf-8', 'strict')) signal.refresh_from_db() self.assertEqual(signal.status.state, workflow.AFGEHANDELD_EXTERN) self.assertEqual( signal.status.text, 'Op locatie geweest, niets aangetroffen: Geen reden aangeleverd vanuit THOR' ) self.assertEqual( signal.status.extra_properties, { 'sigmax_datum_afgehandeld': incoming_context['resultaat_datum'], 'sigmax_resultaat': incoming_context['resultaat_omschrijving'], 'sigmax_reden': incoming_context['resultaat_toelichting'], }) self.assertEqual(signal.status.state, workflow.AFGEHANDELD_EXTERN) self.assertEqual(signal.status.state, workflow.AFGEHANDELD_EXTERN)
class TestGenerateOmschrijving(TestCase): def setUp(self): self.signal = SignalFactoryValidLocation( priority__priority=Priority.PRIORITY_HIGH) def test_generate_omschrijving_urgent(self): stadsdeel = self.signal.location.stadsdeel correct = 'SIA-{}.02 URGENT {} {}'.format( self.signal.pk, SIGMAX_STADSDEEL_MAPPING.get(stadsdeel, 'SD--'), self.signal.location.short_address_text) seq_no = '02' self.assertEqual(_generate_omschrijving(self.signal, seq_no), correct) def test_generate_omschrijving_no_stadsdeel_urgent(self): # test that we get SD-- as part of the omschrijving when stadsdeel is missing self.signal.location.stadsdeel = None self.signal.location.save() correct = 'SIA-{}.04 URGENT SD-- {}'.format( self.signal.pk, self.signal.location.short_address_text) seq_no = '04' self.assertEqual(_generate_omschrijving(self.signal, seq_no), correct) def test_stadsdeel_mapping(self): # Check that all known STADSDELEN (city districts) have a code for use # by Sigmax/CityControl. seq_no = '01' for short_code, name in STADSDELEN: self.signal.location.stadsdeel = short_code self.signal.location.save() self.signal.refresh_from_db() self.assertNotRegex(_generate_omschrijving(self.signal, seq_no), 'SD--')
def test_null_stored_handling_message(self): # SIG-3555 old complaints/Signals will have no stored handling messages on their associated CategoryAssignments. # This test fakes that by setting one category's handling message to null and checks that the correct # placeholder is returned. message_1 = None cat1 = CategoryFactory.create(name='cat1', handling_message=message_1) signal = SignalFactoryValidLocation(category_assignment__category=cat1) self.sia_read_write_user.user_permissions.add( Permission.objects.get(codename='sia_can_view_all_categories')) self.client.force_authenticate(user=self.sia_read_write_user) response = self.client.get( f'/signals/v1/private/signals/{signal.id}/history' + '?what=UPDATE_SLA') self.assertEqual(response.status_code, 200) response_json = response.json() self.assertEqual(response_json[0]['description'], EMPTY_HANDLING_MESSAGE_PLACEHOLDER_MESSAGE)
def test_extract_properties(self): signal = SignalFactoryValidLocation() test_context = { 'signal': signal, 'resultaat_toelichting': 'Het probleem is opgelost', 'resultaat_datum': '2018101111485276', 'sequence_number': 20, } test_msg = render_to_string('sigmax/actualiseerZaakstatus_Lk01.xml', test_context) msg_content = _parse_actualiseerZaakstatus_Lk01( test_msg.encode('utf8')) # test uses knowledge of test XML message content self.assertEqual(msg_content['zaak_id'], str(signal.sia_id) + '.20') # TODO clean-up self.assertEqual(msg_content['datum_afgehandeld'], test_context['resultaat_datum']) self.assertEqual(msg_content['resultaat'], 'Er is gehandhaafd') self.assertEqual(msg_content['reden'], test_context['resultaat_toelichting'])
def setUp(self): self.signal = SignalFactoryValidLocation.create() self.sia_read_write_user.user_permissions.add( Permission.objects.get(codename='sia_can_view_all_categories')) self.client.force_authenticate(user=self.sia_read_write_user) # 2 templates for the special cases where there are URL's in the body. All other templates will use the fallback EmailTemplate.objects.create( key=EmailTemplate.SIGNAL_STATUS_CHANGED_AFGEHANDELD, title='Uw melding {{ signal_id }}' f' {EmailTemplate.SIGNAL_STATUS_CHANGED_AFGEHANDELD}', body= '{{ text }} {{ created_at }} {{ status_text }} {{ positive_feedback_url }} ' '{{ negative_feedback_url }}{{ ORGANIZATION_NAME }}') EmailTemplate.objects.create( key=EmailTemplate.SIGNAL_STATUS_CHANGED_REACTIE_GEVRAAGD, title='Uw melding {{ signal_id }}' f' {EmailTemplate.SIGNAL_STATUS_CHANGED_REACTIE_GEVRAAGD}', body= '{{ text }} {{ created_at }} {{ status_text }} {{ reaction_url }} ' '{{ ORGANIZATION_NAME }}')
def test_no_category_filters(self): """ Get all the signals when no category is set """ cat1 = ParentCategoryFactory.create(name='trash') SignalFactoryValidLocation.create(category_assignment__category=cat1) cat2 = ParentCategoryFactory.create(name='animals') SignalFactoryValidLocation.create(category_assignment__category=cat2) SignalFactoryValidLocation.create(category_assignment__category=cat2) response = self.client.get( f'{self.geography_endpoint}/?bbox=4.700000,52.200000,5.000000,52.500000' ) data = response.json() self.assertEqual(3, len(data['features']))
def setUp(self): self.signal: Signal = SignalFactoryValidLocation.create( incident_date_start=timezone.now() - timedelta(days=1), incident_date_end=timezone.now()) self.seq_no = _generate_sequence_number(self.signal)
class TestFeedbackFlow(SignalsBaseApiTestCase): def setUp(self): # Times for various actions (assumes a 14 day window for feedback). self.t_now = '2019-04-01 12:00:00' self.t_creation = '2019-03-01 12:00:00' self.t_expired = '2019-03-02 12:00:00' self.t_received = '2019-03-29 12:00:00' # Setup our test signal and feedback instances with freeze_time(self.t_creation): self.reporter = ReporterFactory() self.signal = SignalFactoryValidLocation( reporter=self.reporter, status__state=workflow.AFGEHANDELD, ) with freeze_time(self.t_now): self.feedback = FeedbackFactory( submitted_at=None, _signal=self.signal, ) with freeze_time(self.t_expired): self.feedback_expired = FeedbackFactory( submitted_at=None, _signal=self.signal, ) with freeze_time(self.t_received): self.feedback_received = FeedbackFactory( submitted_at=timezone.now() - timedelta(days=5), _signal=self.signal, ) # Setup a standard answer that triggers a request to reopen. self.sa_reopens = StandardAnswerFactory.create( text='Ik ben niet blij met de afhandeling, duurde te lang.', is_satisfied=False, reopens_when_unhappy=True, ) self.sa_no_sideeffect = StandardAnswerFactory.create( text='Ik ben niet blij. Blah, blah.', is_satisfied=False, reopens_when_unhappy=False, ) def test_setup(self): self.assertEqual(Feedback.objects.count(), 3) def test_404_if_no_feedback_requested(self): response = self.client.get('/forms/DIT_IS_GEEN_token/') self.assertEqual(response.status_code, 404) def test_410_gone_too_late(self): token = self.feedback_expired.token with freeze_time(self.t_now): response = self.client.get('/forms/{}/'.format(token)) self.assertEqual(response.status_code, 410) # faalt! self.assertEqual(response.json()['detail'], 'too late') response = self.client.put('/forms/{}/'.format(token), data={}) self.assertEqual(response.status_code, 410) self.assertEqual(response.json()['detail'], 'too late') def test_410_gone_filled_out(self): """Test that we receive correct HTTP 410 reply when form filled out already""" token = self.feedback_received.token with freeze_time(self.t_now): response = self.client.get('/forms/{}/'.format(token)) self.assertEqual(response.status_code, 410) self.assertEqual(response.json()['detail'], 'filled out') response = self.client.put('/forms/{}/'.format(token), data={}) self.assertEqual(response.status_code, 410) self.assertEqual(response.json()['detail'], 'filled out') def test_200_if_feedback_requested(self): """Test that we receive an empty JSON object HTTP 200 reply.""" token = self.feedback.token with freeze_time(self.t_now): response = self.client.get('/forms/{}/'.format(token)) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), {}) def test_200_on_submit_feedback(self): """Test that the feedback can be PUT once.""" token = self.feedback.token reason = 'testen is leuk' explanation = 'ook voor de lunch' data = { 'is_satisfied': True, 'allows_contact': True, 'text': reason, 'text_area': explanation, } with freeze_time(self.t_now): response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) self.feedback.refresh_from_db() self.assertEqual(self.feedback.is_satisfied, True) self.assertEqual(self.feedback.allows_contact, True) self.assertEqual(self.feedback.text, reason) def test_400_on_submit_feedback_without_is_satisfied(self): """Test that the feedback can be PUT once.""" token = self.feedback.token reason = 'testen is leuk' explanation = 'ook voor de lunch' data = { 'allows_contact': True, 'text': reason, 'text_area': explanation, } with freeze_time(self.t_now): response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 400) def test_reopen_requested_on_unsatisfied_standard_answer(self): """Certain standard answers (in feedback) lead to "reopen requested" state.""" token = self.feedback.token data = { 'allows_contact': False, 'text': self.sa_reopens.text, 'is_satisfied': False, } with freeze_time(self.t_now): response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) self.signal.refresh_from_db() self.assertEqual(self.signal.status.state, workflow.VERZOEK_TOT_HEROPENEN) def test_reopen_requested_on_unsatisfied_custom_answer(self): """All custom unsatisfied answers (in feedback) lead to "reopen requested" state.""" token = self.feedback.token data = { 'allows_contact': False, 'text': 'MEH, probleem niet opgelost.', 'is_satisfied': False, } with freeze_time(self.t_now): response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) self.signal.refresh_from_db() self.assertEqual(self.signal.status.state, workflow.VERZOEK_TOT_HEROPENEN) def test_no_reopen_requested_on_unsatisfied_and_known_feedback(self): """Some negative feedback is explicitly marked not to trigger reopen requested.""" token = self.feedback.token data = { 'allows_contact': False, 'text': self.sa_no_sideeffect.text, 'is_satisfied': False, } with freeze_time(self.t_now): response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) self.signal.refresh_from_db() self.assertEqual(self.signal.status.state, workflow.AFGEHANDELD) def test_no_reopen_requested_when_not_in_state_afgehandeld(self): """Only request reopen from AFGEHANDELD state.""" with freeze_time(self.t_now): # Reopen the test signal (so it is no longer in AFGEHANDELD). payload = { 'text': 'De melder is niet tevreden blijkt uit feedback. Zo nodig heropenen.', 'state': workflow.HEROPEND, } Signal.actions.update_status(payload, self.signal) # Send feedback that potentially reopens a signal (should not happen in this test). token = self.feedback.token data = { 'allows_contact': False, 'text': self.sa_reopens.text, 'is_satisfied': False, } response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) # Assert that nothing happened. self.signal.refresh_from_db() self.assertEqual(self.signal.status.state, workflow.HEROPEND) def test_no_reopen_requested_on_positive_feedback(self): """Positive feedback should never request a reopen""" # Create a positive feedback StandardAnswer that could possibly lead to # the status reopen requested. sa_positive = StandardAnswerFactory.create( text='Ik ben blij met de afhandeling.', is_satisfied=True, reopens_when_unhappy=True, ) status_id_before = self.signal.status.id with freeze_time(self.t_now): # Send feedback that potentially reopens a signal (should not happen in this test). token = self.feedback.token data = { 'allows_contact': False, 'text': sa_positive.text, 'is_satisfied': True, # should not be able to override, refactor into separate test } response = self.client.put( '/forms/{}/'.format(token), data=data, format='json', ) self.assertEqual(response.status_code, 200) # Assert that nothing happened. self.signal.refresh_from_db() self.assertEqual(self.signal.status.state, workflow.AFGEHANDELD) self.assertEqual(status_id_before, self.signal.status.id)
def setUp(self): self.signal = SignalFactoryValidLocation( priority__priority=Priority.PRIORITY_HIGH)
def test_generate_voegZaakdocumentToe_Lk01_escaping(self): poison = SignalFactoryValidLocation.create() poison.text = '<poison>tastes nice</poison>' seq_no = '02' xml_message = _generate_voegZaakdocumentToe_Lk01(poison, seq_no) self.assertTrue('<poison>' not in xml_message)
def setUp(self): self.endpoint_url = '/public/map-signals/' self.signal1 = SignalFactoryValidLocation.create() self.signal2 = SignalFactoryValidLocation.create() super().setUp()
def setUp(self): self.signal: Signal = SignalFactoryValidLocation.create() self.seq_no = _generate_sequence_number(self.signal)
def setUp(self): self.signal = SignalFactoryValidLocation.create() # Some Signals that should not have and get any log rules during these tests self.signals_no_log = SignalFactoryValidLocation.create_batch(4)