def setUp(self): # Create two areas, and one areatype # create 3 signals, 1 for area A, 1 for area B and one outside self.area_type_district = AreaTypeFactory.create(code='district', name='district') min_lon, min_lat, max_lon, max_lat = BBOX extent_lon = max_lon - min_lon extent_lat = max_lat - min_lat w = Polygon.from_bbox((min_lon, min_lat, min_lon + extent_lon * 0.5, min_lat + extent_lat)) e = Polygon.from_bbox((min_lon + extent_lon * 0.5, min_lat, min_lon + extent_lon, min_lat + extent_lat)) AreaFactory.create(name='west', code='west', _type=self.area_type_district, geometry=MultiPolygon([w])) AreaFactory.create(name='east', code='east', _type=self.area_type_district, geometry=MultiPolygon([e])) center_w = Point( (min_lon + 0.25 * extent_lon, min_lat + 0.5 * extent_lat)) center_e = Point( (min_lon + 0.75 * extent_lon, min_lat + 0.5 * extent_lat)) to_north = Point( (min_lon + 0.5 * extent_lon, min_lat + 2 * extent_lat)) self.signal_west = SignalFactory.create(location__geometrie=center_w, location__area_type_code=None, location__area_code=None, location__area_name=None) self.signal_east = SignalFactory.create(location__geometrie=center_e, location__area_type_code=None, location__area_code=None, location__area_name=None) self.signal_north = SignalFactory.create(location__geometrie=to_north, location__area_type_code=None, location__area_code=None, location__area_name=None)
def test_save_and_rotate_zip(self, mocked_get_storage_backend): # Mocking the storage backend to local file system with tmp directory. # In this test case we don't want to make usage of the remote Object # Store. mocked_get_storage_backend.return_value = FileSystemStorage(location=self.file_backend_tmp_dir) # Creating a few objects in the database. for i in range(3): SignalFactory.create() # force certain output name with freeze_time('2020-09-10T14:00:00+00:00'): datawarehouse.save_and_zip_csv_files_endpoint(max_csv_amount=1) with freeze_time('2020-09-10T15:00:00+00:00'): datawarehouse.save_and_zip_csv_files_endpoint(max_csv_amount=1) src_folder = f'{self.file_backend_tmp_dir}/2020/09/10' list_of_files = glob(f'{src_folder}/*.zip', recursive=True) self.assertEqual(1, len(list_of_files)) self.assertTrue(list_of_files[0].endswith('20200910_150000UTC.zip'))
def test_save_csv_files_datawarehouse(self, mocked_get_storage_backend): # Mocking the storage backend to local file system with tmp directory. # In this test case we don't want to make usage of the remote Object # Store. mocked_get_storage_backend.return_value = FileSystemStorage( location=self.file_backend_tmp_dir) # Creating a few objects in the database. for i in range(3): SignalFactory.create() datawarehouse.save_csv_files_datawarehouse() # Checking if we have files on the correct locations and that they # do have some content. signals_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_signals.csv') locations_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_locations.csv') reporters_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_reporters.csv') categories_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_categories.csv') statuses_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_statuses.csv') sla_csv = path.join(self.file_backend_tmp_dir, '2020/09/10', '120000UTC_sla.csv') directing_departments_csv = path.join( self.file_backend_tmp_dir, '2020/09/10', '120000UTC_directing_departments.csv') # noqa self.assertTrue(path.exists(signals_csv)) self.assertTrue(path.getsize(signals_csv)) self.assertTrue(path.exists(locations_csv)) self.assertTrue(path.getsize(locations_csv)) self.assertTrue(path.exists(reporters_csv)) self.assertTrue(path.getsize(reporters_csv)) self.assertTrue(path.exists(categories_csv)) self.assertTrue(path.getsize(categories_csv)) self.assertTrue(path.exists(statuses_csv)) self.assertTrue(path.getsize(statuses_csv)) self.assertTrue(path.getsize(sla_csv)) self.assertTrue(path.getsize(directing_departments_csv))
def test_make_email_context_backwards_compatibility(self): """ TODO: should be removed a.s.a.p. """ signal = SignalFactory.create() context = make_email_context(signal=signal) self.assertEqual(context['signal'].id, signal.id) self.assertEqual(context['status']._signal_id, signal.id) self.assertEqual(context['status'].state, signal.status.state)
def test_organization_name_contains_quote(self): signal = SignalFactory.create(reporter__email='*****@*****.**') with self.settings(ORGANIZATION_NAME='Gemeente \'s-Hertogenbosch'): MailService.status_mail(signal=signal) self.assertEqual(f'Template title {signal.id}', mail.outbox[0].subject) self.assertEqual( f'Template title\n\nThanks a lot for reporting {signal.id} {signal.text}\n' f'Gemeente \'s-Hertogenbosch\n\n', mail.outbox[0].body)
def test_anonymize_reporters_less_than_x_days_ago(self): allowed_states = [AFGEHANDELD, GEANNULEERD, GESPLITST, VERZOEK_TOT_AFHANDELING] with freeze_time(timezone.now() - timezone.timedelta(days=1)): for allowed_state in allowed_states: SignalFactory.create(status__state=allowed_state) self.assertEqual(Reporter.objects.count(), 4) anonymize_reporters(days=2) self.assertEqual(Reporter.objects.count(), 4) self.assertEqual(Reporter.objects.filter(Q(email_anonymized=True) | Q(phone_anonymized=True)).count(), 0) self.assertEqual(Reporter.objects.filter(email_anonymized=False, phone_anonymized=False).count(), 4) for reporter in Reporter.objects.all(): self.assertIsNotNone(reporter.email) self.assertIsNotNone(reporter.phone) self.assertFalse(reporter.email_anonymized) self.assertFalse(reporter.phone_anonymized)
def test_add_attachment_extension_not_allowed(self): signal = SignalFactory.create() doc_upload = os.path.join(SIGNALS_TEST_DATA_DIR, 'sia-ontwerp-testfile.doc') with open(doc_upload, encoding='latin-1') as f: data = {"file": f} response = self.client.post(self.attachment_endpoint.format(uuid=signal.uuid), data) self.assertEqual(response.status_code, 400)
def test_organization_name_contains_quote(self): signal = SignalFactory.create(reporter__email=self.get_email()) with self.settings(ORGANIZATION_NAME='Gemeente \'s-Hertogenbosch'): ma = MailActions(mail_rules=SIGNAL_MAIL_RULES) ma.apply(signal_id=signal.id) self.assertEqual(f'Template title {signal.id}', mail.outbox[0].subject) self.assertEqual( f'Template title\n\nThanks a lot for reporting {signal.id} {signal.text}\n' f'Gemeente \'s-Hertogenbosch\n\n', mail.outbox[0].body)
def test_signal_set_state_multiple_times(self): signal = SignalFactory.create(status__state=self.state, reporter__email='*****@*****.**') for x in range(5): with freeze_time(timezone.now() + timedelta(hours=x)): status = StatusFactory.create(_signal=signal, state=self.state) signal.status = status signal.save() self.assertFalse(self.rule(signal))
def test_multiple_extra_properties_for_trees(self): extra_properties = copy.deepcopy(self.extra_properties) extra_properties.append({ 'id': 'extra_eikenprocessierups', 'label': 'Boom', 'answer': [ { 'id': 'ID011', 'type': 'Eikenboom', 'GlobalID': '00000000-0000-0000-0000-000000000000', 'isReported': False, 'description': 'Eikenboom' }, # noqa { 'id': 'ID012', 'type': 'Eikenboom', 'GlobalID': '00000000-0000-0000-0000-000000000000', 'isReported': False, 'description': 'Eikenboom' }, # noqa { 'id': 'ID013', 'type': 'Eikenboom', 'GlobalID': '00000000-0000-0000-0000-000000000000', 'isReported': False, 'description': 'Eikenboom' }, # noqa { 'id': 'ID014', 'type': 'Eikenboom', 'GlobalID': '00000000-0000-0000-0000-000000000000', 'isReported': False, 'description': 'Eikenboom' }, # noqa ], 'category_url': '/signals/v1/public/terms/categories/openbaar-groen-en-water/sub_categories/eikenprocessierups' # noqa }) signal = SignalFactory.create( extra_properties=extra_properties, category_assignment__category=self.category_eikenprocessierups) self.assertFalse(signal.is_parent) self.assertEqual(signal.children.count(), 0) AutoCreateChildrenService.run(signal_id=signal.pk) signal.refresh_from_db() self.assertTrue(signal.is_parent) self.assertEqual(signal.children.count(), 8)
def test_get_by_uuid_access_status(self): # SIA must not publicly expose what step in the resolution process a certain # Signal/melding is signal = SignalFactory.create(status__state=workflow.GEMELD) response = self.client.get(self.detail_endpoint.format(uuid=signal.uuid), format='json') response_json = response.json() self.assertEqual(200, response.status_code) self.assertJsonSchema(self.retrieve_schema, response_json) self.assertEqual(response_json['status']['state'], 'OPEN') signal = SignalFactory.create(status__state=workflow.AFGEHANDELD) response = self.client.get(self.detail_endpoint.format(uuid=signal.uuid), format='json') response_json = response.json() self.assertEqual(200, response.status_code) self.assertJsonSchema(self.retrieve_schema, response_json) self.assertEqual(response_json['status']['state'], 'CLOSED')
def test_send_email_fails(self, mocked): mocked.return_value = False self.assertEqual(len(mail.outbox), 0) status_text = FuzzyText(length=400) signal = SignalFactory.create(status__state=self.state, status__text=status_text, status__send_email=True, reporter__email='*****@*****.**') self.assertFalse(self.action(signal, dry_run=False)) self.assertEqual(len(mail.outbox), 0)
def test_send_mail_integration_test(self): signal = SignalFactory.create( category_assignment__category__parent__name= 'Overlast Bedrijven en Horeca', category_assignment__category__name='Geluidsoverlast muziek') number_of_messages = flex_horeca_mail.send_mail(signal) self.assertEqual(number_of_messages, 1) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Nieuwe melding op meldingen.amsterdam.nl')
def test_send_email_lambda_actions(self): MailService._status_actions = (lambda x, dry_run: False, lambda x, dry_run: False, lambda x, dry_run: False, lambda x, dry_run: False) self.assertEqual(len(mail.outbox), 0) signal = SignalFactory.create(status__state=workflow.GEMELD, reporter__email='*****@*****.**') self.assertFalse(MailService.status_mail(signal.pk)) self.assertEqual(len(mail.outbox), 0)
def test_get_by_uuid_cannot_access_properties(self): # SIA must not publicly expose operational date, expire_date and attachments signal = SignalFactory.create() response = self.client.get(self.detail_endpoint.format(uuid=signal.uuid), format='json') response_json = response.json() self.assertEqual(200, response.status_code) self.assertJsonSchema(self.retrieve_schema, response_json) self.assertNotIn('operational_date', response_json) self.assertNotIn('expire_date', response_json) self.assertNotIn('attachments', response_json)
def test_send_email_anonymous(self): self.assertEqual(len(mail.outbox), 0) status_text = FuzzyText(length=400) signal = SignalFactory.create(status__state=self.state, status__text=status_text, status__send_email=self.send_email, reporter__email='') self.assertFalse(self.action(signal, dry_run=False)) self.assertEqual(len(mail.outbox), 0) self.assertEqual(Note.objects.count(), 0) self.assertFalse(Note.objects.filter(text=self.action.note).exists()) signal = SignalFactory.create(status__state=self.state, status__text=status_text, status__send_email=self.send_email, reporter__email=None) self.assertFalse(self.action(signal, dry_run=False)) self.assertEqual(len(mail.outbox), 0) self.assertEqual(Note.objects.count(), 0) self.assertFalse(Note.objects.filter(text=self.action.note).exists())
def test_get_session_frozen(self): # A session that is frozen should raise SessionFrozen signal = SignalFactory.create(status__state=workflow.GEMELD) session = SessionFactory.create( _signal=signal, questionnaire__flow=Questionnaire.REACTION_REQUEST, frozen=True) session_service = get_session_service(session.uuid) session_service.refresh_from_db() with self.assertRaises(SessionFrozen) as cm: session_service.is_publicly_accessible() self.assertIn('Already used!', str(cm.exception))
def test_get_geojson_bbox_filter(self): """ Return the GEOJson containing all signals in the child category in a certain bbox """ 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))): # Should appear in the response SignalFactory.create( location__geometrie=Point(STADHUIS['lon'], STADHUIS['lat']), location__buurt_code=STADHUIS['buurt_code'], category_assignment__category=child_category) # Should not appear in the response SignalFactory.create( location__geometrie=Point(ARENA['lon'], ARENA['lat']), location__buurt_code=ARENA['buurt_code'], 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.875759,52.360656,4.921221,52.37942' ) 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_add_attachment_imagetype(self): signal = SignalFactory.create() data = {"file": SimpleUploadedFile('image.gif', small_gif, content_type='image/gif')} response = self.client.post(self.attachment_endpoint.format(uuid=signal.uuid), data) self.assertEqual(201, response.status_code) self.assertJsonSchema(self.create_attachment_schema, response.json()) attachment = Attachment.objects.last() self.assertEqual("image/gif", attachment.mimetype) self.assertIsNone(attachment.created_by)
def test_get_by_uuid__display_is_clean(self): # SIA must not publicly expose what step in the resolution process a certain # Signal/melding is via the _display string. signal = SignalFactory.create() response = self.client.get(self.detail_endpoint.format(uuid=signal.uuid), format='json') response_json = response.json() self.assertEqual(200, response.status_code) self.assertJsonSchema(self.retrieve_schema, response_json) # For backwards compatibility the _display string is not changed, we use the # fact that it is derived from the __str__ representation, to do this check. self.assertNotEqual(response_json['_display'], str(signal))
def setUp(self): self.signal = SignalFactory.create() self.feedback_submitted = FeedbackFactory.create( _signal=self.signal, created_at=datetime(2019, 4, 9, 12, 0, tzinfo=pytz.UTC), submitted_at=datetime(2019, 4, 9, 18, 0, 0, tzinfo=pytz.UTC), text='Tevreden want mooi weer', text_extra='Waarom? Daarom!') self.feedback_requested = FeedbackFactory.create( _signal=self.signal, created_at=datetime(2019, 4, 9, 12, 0, 0), ) self.csv_tmp_dir = tempfile.mkdtemp()
def test_filter_directing_department_mixed(self): department = DepartmentFactory.create() parent_one = SignalFactory.create() SignalFactory.create_batch(1, parent=parent_one) directing_departments = SignalDepartments.objects.create( _signal=parent_one, created_by='*****@*****.**', relation_type='directing') directing_departments.departments.add(department) directing_departments.save() parent_one.directing_departments_assignment = directing_departments parent_one.save() parent_two = SignalFactory.create() SignalFactory.create_batch(2, parent=parent_two) params = {'directing_department': ['null', department.code]} result_ids = self._request_filter_signals(params) self.assertEqual(2, len(result_ids))
def test_evil_input(self): evil_signal = SignalFactory.create( reporter__email='*****@*****.**', text='<script>alert("something evil");</script>') MailService.status_mail(signal=evil_signal) self.assertEqual(f'Template title {evil_signal.id}', mail.outbox[0].subject) self.assertEqual( f'Template title\n\nThanks a lot for reporting {evil_signal.id} ' f'alert("something evil");\n{settings.ORGANIZATION_NAME}\n\n', mail.outbox[0].body)
def test_questionnaire(self): signal = SignalFactory.create(status__state=workflow.AFGEHANDELD) session = create_session_for_feedback_request(signal) questionnaire = session.questionnaire graph = questionnaire.graph self.assertEqual(questionnaire.first_question.analysis_key, 'satisfied') # TODO: use QuestionGraphService: all_questions = Question.objects.get_from_question_graph(graph) self.assertEqual(all_questions.count(), 5) # TODO: use QuestionGraphService: reachable_questions = Question.objects.get_reachable_from_question_graph(graph) self.assertEqual(reachable_questions.count(), 5)
def test_make_email_context(self): signal = SignalFactory.create() context = make_email_context(signal=signal) self.assertEqual(context['signal_id'], signal.id) self.assertEqual(context['formatted_signal_id'], signal.sia_id) self.assertEqual(context['created_at'], signal.created_at) self.assertEqual(context['text'], signal.text) self.assertEqual(context['text_extra'], signal.text_extra) self.assertEqual(context['address'], signal.location.address) self.assertEqual(context['status_text'], signal.status.text) self.assertEqual(context['status_state'], signal.status.state) self.assertEqual(context['handling_message'], signal.category_assignment.stored_handling_message) self.assertEqual(context['ORGANIZATION_NAME'], settings.ORGANIZATION_NAME)
def test_evil_input(self): evil_signal = SignalFactory.create( reporter__email=self.get_email(), text='<script>alert("something evil");</script>') ma = MailActions(mail_rules=SIGNAL_MAIL_RULES) ma.apply(signal_id=evil_signal.id) self.assertEqual(f'Template title {evil_signal.id}', mail.outbox[0].subject) self.assertEqual( f'Template title\n\nThanks a lot for reporting {evil_signal.id} ' f'alert("something evil");\n{settings.ORGANIZATION_NAME}\n\n', mail.outbox[0].body)
def test_no_trees_selected(self): signal = SignalFactory.create( extra_properties=None, category_assignment__category=self.category_eikenprocessierups) self.assertFalse(signal.is_parent) self.assertEqual(signal.children.count(), 0) AutoCreateChildrenService.run(signal_id=signal.pk) signal.refresh_from_db() self.assertFalse(signal.is_parent) self.assertEqual(signal.children.count(), 0)
def test_gesplits_parent_and_child_signals_should_be_deleted(self): """ Parent signal created 370 days ago and the final state set 369 days ago. So the signal and its children should be deleted. """ self.feature_flags['DELETE_SIGNALS_IN_STATE_X_AFTER_PERIOD_Y_ENABLED'] = True with freeze_time(timezone.now() - timezone.timedelta(days=370)): parent_signal = SignalFactory.create(status__state=GESPLITST) child_signal = SignalFactory.create(parent=parent_signal) buffer = StringIO() with override_settings(FEATURE_FLAGS=self.feature_flags): call_command('delete_signals', GESPLITST, '365', stdout=buffer) output = buffer.getvalue() self.assertIn(f'Deleted Signal: #{parent_signal.id}', output) self.assertFalse(Signal.objects.filter(id=parent_signal.id).exists()) self.assertTrue(DeletedSignal.objects.filter(signal_id=parent_signal.id).exists()) self.assertIn(f'Deleted Signal: #{child_signal.id}', output) self.assertFalse(Signal.objects.filter(id=child_signal.id).exists()) self.assertTrue(DeletedSignal.objects.filter(signal_id=child_signal.id).exists())
def test_send_mail(self, mocked_create_default_notification_message, mocked_django_send_mail): mocked_message = mock.Mock() mocked_create_default_notification_message.return_value = mocked_message signal = SignalFactory.create() number_of_messages = toezicht_or_nieuw_west_mail.send_mail(signal) self.assertEqual(number_of_messages, 1) mocked_django_send_mail.assert_called_once_with( subject='Nieuwe melding op meldingen.amsterdam.nl', message=mocked_message, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=['*****@*****.**', ] )
def test_generate_creeerZaak_Lk01_priority_low(self): current_tz = timezone.get_current_timezone() signal = SignalFactory.create(incident_date_end=None, priority__priority=Priority.PRIORITY_LOW) seq_no = _generate_sequence_number(signal) xml_message = _generate_creeerZaak_Lk01(signal, seq_no) self.assertXmlDocument(xml_message) incident_date_end = signal.created_at + timedelta(days=3) self.assertIn( '<ZKN:einddatumGepland>{}</ZKN:einddatumGepland>'.format( incident_date_end.astimezone(current_tz).strftime('%Y%m%d')), xml_message)