def test_pipeline_data_for_rule_raises_future_exception(days_in_future): """Ensure function under test raises DateForCannotBeFutureError for future dates """ arg_date = datetime.utcnow().replace(tzinfo=utc) + timedelta( days=days_in_future) with pytest.raises(DateForCannotBeFutureError): pipeline_date_for_rule(arg_date)
def run_pipeline_date_for_rule_asserts(arg_datetime, expected_date): """Validate function works with different parameter types """ assert pipeline_date_for_rule(arg_datetime) == expected_date # test as date assert pipeline_date_for_rule(arg_datetime.date()) == expected_date # test as string rep of datetime assert pipeline_date_for_rule(str(arg_datetime)) == expected_date # test as string rep of date assert pipeline_date_for_rule(str(arg_datetime.date())) == expected_date
def load(self, date_for=None, force_update=False, **_kwargs): """ TODO: clean up how we do this. We want to be able to call the loader with an existing data set (not having to call the extractor) but we need to make sure that the metrics row 'date_for' is the same as provided in the data. So before hacking something together, I want to think this over some more. If the record alrdady exists and force_update is False, then simply return the record with the 'created' flag to False. This saves us an unnecessary call to extract data Raises ValidationError if invalid data is attempted to be saved to the course daily metrics model instance """ date_for = pipeline_date_for_rule(date_for) try: cdm = CourseDailyMetrics.objects.get(course_id=str(self.course_id), date_for=date_for) # record found, only update if force update flag is True if not force_update: return (cdm, False,) except CourseDailyMetrics.DoesNotExist: # record not found, move on to creating pass data = self.get_data(date_for=date_for) return self.save_metrics(date_for=date_for, data=data)
def test_pipeline_date_for_rule_get_yesterday_with_none(): """Ensure function under test returns yesterday as a datetime.date instance """ now = datetime.utcnow().replace(tzinfo=utc) date_for = pipeline_date_for_rule(None) assert isinstance(date_for, date) assert date_for == now.date() - timedelta(days=1)
def load(self, site, date_for=None, force_update=False, **_kwargs): """ Architectural note: Initially, we're going to be explicit, requiring callers to specify the site model instance to be associated with the site specific metrics model(s) we are populating TODOs: Add filtering for * Multi-tenancy * Course acess groups """ date_for = pipeline_date_for_rule(date_for) # if we already have a record for the date_for and force_update is False # then skip getting data if not force_update: try: sdm = SiteDailyMetrics.objects.get(site=site, date_for=date_for) return ( sdm, False, ) except SiteDailyMetrics.DoesNotExist: # proceed normally pass data = self.extractor.extract(site=site, date_for=date_for) site_metrics, created = SiteDailyMetrics.objects.update_or_create( date_for=date_for, site=site, defaults=dict( cumulative_active_user_count=data[ 'cumulative_active_user_count'], todays_active_user_count=data['todays_active_user_count'], total_user_count=data['total_user_count'], course_count=data['course_count'], total_enrollment_count=data['total_enrollment_count'], mau=data['mau'], )) return site_metrics, created