def setUp(self): super(ShipmentPackageMapViewTest, self).setUp() self.package = PackageFactory(shipment=self.shipment, code=QR_CODE) form_data = PackageScanFormSubmission(json.loads(PACKAGE_DATA)) FormSubmission.from_ona_form_data(form_data) self.url = reverse('shipments_package_map', kwargs={'pk': self.package.pk})
def verify_deviceid(): """Store the DeviceID and QR code""" last_retrieval = None try: form_id = settings.ONA_DEVICEID_VERIFICATION_FORM_ID if form_id in bad_form_ids: return client = OnaApiClient() # Make sure the form exists before we try to get submissions form_defn = client.get_form_definition(form_id) if not form_defn: # Logging an error should result in an email to the admins so they # know to fix this. logger.error("Bad ONA_DEVICEID_VERIFICATION_FORM_ID: %s" % form_id) # Let's not keep trying for the bad form ID. We'll have to change the # settings and restart to fix it. bad_form_ids.add(form_id) return last_retrieval, unused = LastFormRetrievalTimestamp.objects.get_or_create(form_id=form_id) try: submissions = client.get_form_submissions(form_id, since=last_retrieval.timestamp) except Http404: logger.error( "Got 404 getting submissions for ONA_DEVICEID_VERIFICATION_FORM_ID = %s" % form_id) return except OnaApiClientException as e: if e.status_code != 404: raise logger.error( "Got 404 getting submissions for ONA_DEVICEID_VERIFICATION_FORM_ID = %s" % form_id) return # add the form definition JSON to each submission for data in submissions: data.update({'form_id': form_id}) # create a list of API repr objects and ensure they are sorted by submission date objects = [OnaItemBase(x) for x in submissions] objects.sort(key=lambda x: x._submission_time) for submission in objects: if submission._submission_time > last_retrieval.timestamp: last_retrieval.timestamp = submission._submission_time valid_code = CtsUser.objects.filter(code=submission.qr_code).exists() if valid_code: if not FormSubmission.objects.filter(uuid=submission._uuid).exists(): FormSubmission.from_ona_form_data(submission) else: # Log an invalid QR Code msg = "FormSubmission with form id of %s has invalid User QR Code: %s" \ % (submission._xform_id_string, submission.qr_code) logger.error(msg) except ConnectionError: logger.exception("Error connecting to Ona server") except Exception: logger.exception("Something blew up in verify_deviceid") finally: if last_retrieval: last_retrieval.save()
def test_record_package_location_no_package(self, mock_logging): """No matching package with the supplied QR code is found""" PackageFactory(code='not-found') self.assertFalse(PackageScan.objects.all()) form_data = PackageScanFormSubmission(json.loads(PACKAGE_DATA)) FormSubmission.from_ona_form_data(form_data) self.assertFalse(PackageScan.objects.all()) self.assertTrue(mock_logging.exception.called)
def test_record_package_location_invalid_status(self, mock_logging): """Invalid current_location ingested""" PackageFactory(code=QR_CODE) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) data["current_location"] = "FOOBAR-Zero_Point" form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertTrue(mock_logging.error.called)
def test_record_package_location_malformed_uuid(self, mock_logging): """Bad UUID""" PackageFactory(code=QR_CODE) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) data['_uuid'] = 'foobar' form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertFalse(PackageScan.objects.all()) self.assertTrue(mock_logging.exception.called)
def test_record_package_scan_no_gps(self): # A scan with no GPS data still updates the package status pkg = PackageFactory(code=QR_CODE, status=Shipment.STATUS_IN_PROGRESS) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) data.pop('gps') form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) # Yes, we have a scan self.assertTrue(PackageScan.objects.all()) self.assertEqual(Shipment.STATUS_IN_TRANSIT, PackageDBView.objects.get(pk=pkg.pk).status)
def test_record_package_location_valid_status_in_transit(self, mock_logging): """Valid current_location ingested""" date_picked_up = now() PackageFactory(code=QR_CODE, date_picked_up=date_picked_up) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertFalse(mock_logging.error.called) scan = PackageScan.objects.all()[0] self.assertEqual(scan.package.status, Shipment.STATUS_IN_TRANSIT) self.assertEqual(scan.package.shipment.status, Shipment.STATUS_IN_TRANSIT) self.assertEqual(scan.package.date_picked_up, date_picked_up) self.assertEqual(scan.package.date_in_transit, form_data._submission_time) self.assertEqual(scan.package.date_received, None)
def test_record_package_location_valid_status_picked_up(self, mock_logging): """Valid current_location ingested""" PackageFactory(code=QR_CODE) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) data['current_location'] = "STATUS_PICKED_UP-something" form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertFalse(mock_logging.error.called) scan = PackageScan.objects.all()[0] self.assertEqual(scan.package.status, Shipment.STATUS_PICKED_UP) self.assertEqual(scan.package.shipment.status, Shipment.STATUS_PICKED_UP) self.assertEqual(scan.package.date_picked_up, form_data._submission_time) self.assertEqual(scan.package.date_in_transit, None) self.assertEqual(scan.package.date_received, None)
def test_record_package_location_valid_status_in_transit( self, mock_logging): """Valid current_location ingested""" date_picked_up = now() PackageFactory(code=QR_CODE, date_picked_up=date_picked_up) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertFalse(mock_logging.error.called) scan = PackageScan.objects.all()[0] self.assertEqual(scan.package.status, Shipment.STATUS_IN_TRANSIT) self.assertEqual(scan.package.shipment.status, Shipment.STATUS_IN_TRANSIT) self.assertEqual(scan.package.date_picked_up, date_picked_up) self.assertEqual(scan.package.date_in_transit, form_data._submission_time) self.assertEqual(scan.package.date_received, None)
def test_record_package_location_valid_status_picked_up( self, mock_logging): """Valid current_location ingested""" PackageFactory(code=QR_CODE) self.assertFalse(PackageScan.objects.all()) data = json.loads(PACKAGE_DATA) data['current_location'] = "STATUS_PICKED_UP-something" form_data = PackageScanFormSubmission(data) FormSubmission.from_ona_form_data(form_data) self.assertFalse(mock_logging.error.called) scan = PackageScan.objects.all()[0] self.assertEqual(scan.package.status, Shipment.STATUS_PICKED_UP) self.assertEqual(scan.package.shipment.status, Shipment.STATUS_PICKED_UP) self.assertEqual(scan.package.date_picked_up, form_data._submission_time) self.assertEqual(scan.package.date_in_transit, None) self.assertEqual(scan.package.date_received, None)
def setUp(self): super(ShipmentDashboardViewTest, self).setUp() self.package = PackageFactory(shipment=self.shipment, code=QR_CODE) form_data = PackageScanFormSubmission(json.loads(PACKAGE_DATA)) FormSubmission.from_ona_form_data(form_data) self.url = reverse('shipments_dashboard')
def test_record_voucher_location(self): PackageFactory(code=QR_CODE) self.assertFalse(PackageScan.objects.all()) form_data = PackageScanFormSubmission(json.loads(VOUCHER_DATA)) FormSubmission.from_ona_form_data(form_data) self.assertTrue(PackageScan.objects.all())
def verify_deviceid(): """Store the DeviceID and QR code""" last_retrieval = None try: form_id = settings.ONA_DEVICEID_VERIFICATION_FORM_ID if form_id in bad_form_ids: return client = OnaApiClient() # Make sure the form exists before we try to get submissions form_defn = client.get_form_definition(form_id) if not form_defn: # Logging an error should result in an email to the admins so they # know to fix this. logger.error("Bad ONA_DEVICEID_VERIFICATION_FORM_ID: %s" % form_id) # Let's not keep trying for the bad form ID. We'll have to change the # settings and restart to fix it. bad_form_ids.add(form_id) return last_retrieval, unused = LastFormRetrievalTimestamp.objects.get_or_create( form_id=form_id) try: submissions = client.get_form_submissions( form_id, since=last_retrieval.timestamp) except Http404: logger.error( "Got 404 getting submissions for ONA_DEVICEID_VERIFICATION_FORM_ID = %s" % form_id) return except OnaApiClientException as e: if e.status_code != 404: raise logger.error( "Got 404 getting submissions for ONA_DEVICEID_VERIFICATION_FORM_ID = %s" % form_id) return # add the form definition JSON to each submission for data in submissions: data.update({'form_id': form_id}) # create a list of API repr objects and ensure they are sorted by submission date objects = [OnaItemBase(x) for x in submissions] objects.sort(key=lambda x: x._submission_time) for submission in objects: if submission._submission_time > last_retrieval.timestamp: last_retrieval.timestamp = submission._submission_time valid_code = CtsUser.objects.filter( code=submission.qr_code).exists() if valid_code: if not FormSubmission.objects.filter( uuid=submission._uuid).exists(): FormSubmission.from_ona_form_data(submission) else: # Log an invalid QR Code msg = "FormSubmission with form id of %s has invalid User QR Code: %s" \ % (submission._xform_id_string, submission.qr_code) logger.error(msg) except ConnectionError: logger.exception("Error connecting to Ona server") except Exception: logger.exception("Something blew up in verify_deviceid") finally: if last_retrieval: last_retrieval.save()
def process_new_package_scans(): """Updates the local database with new package tracking form submissions""" logger.debug("process_new_package_scans task starting...") try: form_id = int(settings.ONA_PACKAGE_FORM_ID) if form_id in bad_form_ids: return client = OnaApiClient() form_def = client.get_form_definition(form_id) if not form_def: # Logging an error should result in an email to the admins so they # know to fix this. logger.error("Bad ONA_PACKAGE_FORM_ID: %s" % form_id) # Let's not keep trying for the bad form ID. We'll have to change the # settings and restart to fix it. bad_form_ids.add(form_id) return # What's the last submission we got (if any) most_recent_submission = FormSubmission.objects.filter(form_id=form_id)\ .order_by('-submission_time').first() if most_recent_submission: # Don't re-fetch the last form since = most_recent_submission.submission_time logger.debug("Getting forms since %s" % since) else: logger.debug("No form submissions yet for %r" % form_id) since = None try: submissions = client.get_form_submissions(form_id, since=since) except Http404: logger.error( "Got 404 getting submissions for ONA_PACKAGE_FORM_ID = %s" % form_id) return except OnaApiClientException as e: if e.status_code != 404: raise logger.error( "Got 404 getting submissions for ONA_PACKAGE_FORM_ID = %s" % form_id) return logger.debug( "process_new_package_scans downloaded %d submitted forms" % len(submissions)) # add the form definition JSON to each submission for data in submissions: data.update({'form_id': form_id}) data.update({'form_definition': form_def}) # create a list of API repr objects and ensure they are sorted by submission date objects = [PackageScanFormSubmission(x) for x in submissions] objects.sort(key=lambda x: x._submission_time) logger.debug("There are %d objects to look at" % len(objects)) for submission in objects: existing = FormSubmission.objects.filter( uuid=submission._uuid).first() if not existing: logger.debug("Got new form, creating new record") try: FormSubmission.from_ona_form_data(submission) except Exception: logger.exception( "HEY got exception creating new FormSubmission") else: logger.debug("Form %s (%r, %s) already existed" % (submission._uuid, submission.form_id, existing.submission_time)) except ConnectionError: logger.exception("Error connecting to Ona server") except Exception: logger.exception("Something blew up in process_new_package_scans") logger.debug("process_new_package_scans task done")
def process_new_scans(): """Updates the local database with new package tracking form submissions""" logger.debug("process_new_scans task starting...") try: form_ids = [int(x) for x in settings.ONA_FORM_IDS] for form_id in form_ids: if form_id in bad_form_ids: return client = OnaApiClient() if form_id in form_defs: form_def = form_defs[form_id] else: form_def = client.get_form_definition(form_id) if form_def: form_defs[form_id] = form_def else: # Logging an error should result in an email to the admins so they # know to fix this. logger.error("Bad ONA_FORM_ID: %s" % form_id) # Let's not keep trying for the bad form ID. We'll have to change the # settings and restart to fix it. bad_form_ids.add(form_id) return # What's the last submission we got (if any) most_recent_submission = FormSubmission.objects.filter(form_id=form_id)\ .order_by('-submission_time').first() if most_recent_submission: # Don't re-fetch the last form since = most_recent_submission.submission_time logger.debug("Getting forms since %s" % since) else: logger.debug("No form submissions yet for %r" % form_id) since = None try: submissions = client.get_form_submissions(form_id, since=since) except Http404: logger.error( "Got 404 getting submissions for ONA_FORM_ID = %s" % form_id) return except OnaApiClientException as e: if e.status_code != 404: raise logger.error( "Got 404 getting submissions for ONA_FORM_ID = %s" % form_id) return logger.debug( "process_new_scans downloaded %d submitted forms" % len(submissions)) # add the form definition JSON to each submission for data in submissions: data.update({'form_id': form_id}) data.update({'form_definition': form_def}) # create a list of API repr objects and ensure they are sorted by submission date objects = [PackageScanFormSubmission(x) for x in submissions] objects.sort(key=lambda x: x._submission_time) logger.debug("There are %d objects to look at" % len(objects)) for submission in objects: existing = FormSubmission.objects.filter(uuid=submission._uuid).first() if not existing: logger.debug("Got new form, creating new record") try: FormSubmission.from_ona_form_data(submission) except Exception: logger.exception("HEY got exception creating new FormSubmission") else: logger.debug("Form %s (%r, %s) already existed" % (submission._uuid, submission.form_id, existing.submission_time)) except ConnectionError: logger.exception("Error connecting to Ona server") except OnaApiClientException: logger.exception("Error communicating with Ona server") except Exception: logger.exception("Something blew up in process_new_scans") logger.debug("process_new_scans task done")