def testPillboxCheck(self): """ This test tries to accomplish a few things 0: ensure the content of the signal is correctly set 1: verify that the dots_observations view is working correctly in reporting dates correclty back in order 2: Ensure that if you fill out the questions on the form, it won't redundantly fill out the pillbox cells again as well 3: ensure that proper ART/NonART sequences are put in the correct buckets when combined into a "DOTS Day" cell todo: get label day_slot to work correctly """ #check to make sure that 0th and nth elements are where they ought to be #hit the VIEW to make sure it's there #make sure the pact_dots_data signal is working #check no pillbox check entries that entries show up, and NOTHING more. #ensure signal works #todo: labeling checks self.testSignal() observations = query_observations(CASE_ID, START_DATE, END_DATE) td = END_DATE - START_DATE def check_obs_props(obs, props): for k, v in props.items(): if k.endswith("_date"): #datetime check obs_date = getattr(obs, k).date() val_date = dateutil.parser.parse(v).date() self.assertEquals(obs_date, val_date) else: self.assertEquals( getattr(obs, k), v, msg="Error, observation %s\n\t%s didn't match: %s != %s" % (simplejson.dumps(obs.to_json(), indent=4), k, getattr(obs, k), v)) for d in range(td.days): this_day = START_DATE + timedelta(days=d) day_submissions = filter_obs_for_day(this_day.date(), observations) day_data = DOTDay.merge_from_observations(day_submissions) if this_day.date() == START_DATE.date(): art_first = day_data.art.dose_dict[1][0] art_first_check_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 2, "day_note": "art first noon", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", #"day_slot": 1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 1, #zero indexed # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": True, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(art_first, art_first_check_props) non_art_first_1 = day_data.nonart.dose_dict[1][0] non_art_first_1_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art first evening", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", # "day_slot": 2, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_first_1, non_art_first_1_props) non_art_first_2 = day_data.nonart.dose_dict[2][0] non_art_first_2_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art bedtime first", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", # "day_slot": 3, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 2, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_first_2, non_art_first_2_props) if this_day.date() == (ANCHOR_DATE - timedelta(days=1)).date(): self.assertEquals( len(day_data.art.dose_dict.keys()), 2 ) # two doses, one for the answered, another for unchecked art_slast = day_data.art.dose_dict[0][0] art_slast_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 2, "day_note": "2nd to last last filled by questions", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", "day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": True, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(art_slast, art_slast_props) nonart_slast0 = day_data.nonart.dose_dict[0][0] non_art0 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "direct", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "empty", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast0, non_art0) nonart_slast1 = day_data.nonart.dose_dict[1][0] non_art1 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art noon second to last", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast1, non_art1) nonart_slast2 = day_data.nonart.dose_dict[2][0] non_art2 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "art evening second to last", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 2, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast2, non_art2) if this_day.date() == ANCHOR_DATE.date(): self.assertEqual(len(day_data.nonart.dose_dict[0]), 1) non_art_last = day_data.nonart.dose_dict[0][0] non_art_last_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "", "day_index": 0, "note": "Anchor same", "pact_id": "999999", "provider": "ctsims", "method": "direct", "observed_date": "2012-12-07T05:00:00Z", #"day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_last, non_art_last_props) non_art_last_noon = day_data.nonart.dose_dict[1][0] non_art_last_noon_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art noon last", "day_index": 0, "note": "Anchor same", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-07T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_last_noon, non_art_last_noon_props) #todo: check reconciliation? pass
def testPillboxCheck(self): """ This test tries to accomplish a few things 0: ensure the content of the signal is correctly set 1: verify that the dots_observations view is working correctly in reporting dates correclty back in order 2: Ensure that if you fill out the questions on the form, it won't redundantly fill out the pillbox cells again as well 3: ensure that proper ART/NonART sequences are put in the correct buckets when combined into a "DOTS Day" cell todo: get label day_slot to work correctly """ #check to make sure that 0th and nth elements are where they ought to be #hit the VIEW to make sure it's there #make sure the pact_dots_data signal is working #check no pillbox check entries that entries show up, and NOTHING more. #ensure signal works #todo: labeling checks self.testSignal() observations = query_observations(CASE_ID, START_DATE, END_DATE) td = END_DATE - START_DATE def check_obs_props(obs, props): for k, v in props.items(): if k.endswith("_date"): # datetime check obs_datetime = getattr(obs, k) val_datetime = dateutil.parser.parse(v) if k in ('completed_date', 'created_date'): obs_datetime = ServerTime(obs_datetime).user_time(PACT_TIMEZONE).done() obs_date = obs_datetime.date() val_date = val_datetime.date() self.assertEquals(obs_date, val_date) else: self.assertEquals(getattr(obs, k), v, msg="Error, observation %s\n\t%s didn't match: %s != %s" % ( json.dumps(obs.to_json(), indent=4), k, getattr(obs, k), v)) for d in range(td.days): this_day = START_DATE + timedelta(days=d) day_submissions = filter_obs_for_day(this_day.date(), observations) day_data = DOTDay.merge_from_observations(day_submissions) if this_day.date() == START_DATE.date(): art_first = day_data.art.dose_dict[1][0] art_first_check_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 2, "day_note": "art first noon", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", #"day_slot": 1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 1, #zero indexed # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": True, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(art_first, art_first_check_props) non_art_first_1 = day_data.nonart.dose_dict[1][0] non_art_first_1_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art first evening", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", # "day_slot": 2, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_first_1, non_art_first_1_props) non_art_first_2 = day_data.nonart.dose_dict[2][0] non_art_first_2_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art bedtime first", "day_index": 20, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-11-17T05:00:00Z", # "day_slot": 3, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 2, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_first_2, non_art_first_2_props) if this_day.date() == (ANCHOR_DATE - timedelta(days=1)).date(): self.assertEquals(len(day_data.art.dose_dict.keys()), 2) # two doses, one for the answered, another for unchecked art_slast = day_data.art.dose_dict[0][0] art_slast_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 2, "day_note": "2nd to last last filled by questions", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", "day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": True, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(art_slast, art_slast_props) nonart_slast0 = day_data.nonart.dose_dict[0][0] non_art0 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "direct", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "empty", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast0, non_art0) nonart_slast1 = day_data.nonart.dose_dict[1][0] non_art1 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art noon second to last", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast1, non_art1) nonart_slast2 = day_data.nonart.dose_dict[2][0] non_art2 = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "art evening second to last", "day_index": 1, "note": "", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-06T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 2, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(nonart_slast2, non_art2) if this_day.date() == ANCHOR_DATE.date(): self.assertEqual(len(day_data.nonart.dose_dict[0]), 1) non_art_last = day_data.nonart.dose_dict[0][0] non_art_last_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "", "day_index": 0, "note": "Anchor same", "pact_id": "999999", "provider": "ctsims", "method": "direct", "observed_date": "2012-12-07T05:00:00Z", #"day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 0, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_last, non_art_last_props) non_art_last_noon = day_data.nonart.dose_dict[1][0] non_art_last_noon_props = { "encounter_date": "2012-12-07T05:00:00Z", "total_doses": 3, "day_note": "non art noon last", "day_index": 0, "note": "Anchor same", "pact_id": "999999", "provider": "ctsims", "method": "pillbox", "observed_date": "2012-12-07T05:00:00Z", # "day_slot": -1, "completed_date": "2012-12-16T22:00:28.847000Z", "adherence": "partial", "dose_number": 1, # "doc_type": "CObservation", "is_reconciliation": False, "anchor_date": "2012-12-07T05:00:00Z", "created_date": "2012-12-16T21:37:52.771000Z", "is_art": False, "_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759", "doc_id": "a1811d7e-c968-4b63-aea5-6195ce0d8759" } check_obs_props(non_art_last_noon, non_art_last_noon_props) #todo: check reconciliation? pass
def formatday(self, day, weekday): if day != 0: cssclass = self.cssclasses[weekday] this_day = date(self.year, self.month, day) if date.today() == this_day: cssclass += ' today' if date.today() < this_day: future=True else: future=False day_observations = filter_obs_for_day(this_day, self.observations) if len(day_observations) > 0: cssclass += ' filled' body = ['<div class="calendar-cell">'] day_data = DOTDay.merge_from_observations(day_observations) #day_data = merge_dot_day(day_observations) #for drug_type in day_data.keys(): day_notes = set() for dose_data in [day_data.nonart, day_data.art]: body.append('') body.append('<div class="drug-cell">') body.append('<div class="drug-label">%s</div>' % dose_data.drug_class) #drug_total = day_data[drug_type]['total_doses'] drug_total = dose_data.total_doses for dose_num, obs_list in dose_data.dose_dict.items(): if len(obs_list) > 0: obs = obs_list[0] if obs.day_note is not None and len(obs.day_note) > 0: day_notes.add(obs.day_note) if obs.day_slot != '' and obs.day_slot is not None and obs.day_slot != -1: day_slot_string = DAY_SLOTS_BY_IDX.get(int(obs.day_slot), 'Unknown').title() body.append('<div class="time-label">%s</div>' % day_slot_string) else: #do it by seq? body.append('<div class="time-label">Dose %d</div>' % (int(dose_num) + 1)) body.append('<div class="time-cell">') body.append('<div class="observation">') if obs.adherence == DOT_ADHERENCE_UNCHECKED: body.append('<span style="font-size:85%;color:#888;font-style:italic;">unchecked</span>') else: if obs.adherence == DOT_ADHERENCE_EMPTY: # body.append('<span class="label label-success">Empty</span>') body.append('<img src="%spact/icons/check.jpg">' % settings.STATIC_URL) elif obs.adherence == DOT_ADHERENCE_PARTIAL: # body.append('<span class="label label-warning">Partial</span>') body.append('<img src="%spact/icons/exclamation-point.jpg">' % settings.STATIC_URL) elif obs.adherence == DOT_ADHERENCE_FULL: # body.append('<span class="label label-important">Full</span>') body.append('<img src="%spact/icons/x-mark.png">' % settings.STATIC_URL) if obs.method == DOT_OBSERVATION_DIRECT: # body.append('<span class="label label-info">Direct</span>') body.append('<img src="%spact/icons/plus.png">' % settings.STATIC_URL) elif obs.method == DOT_OBSERVATION_PILLBOX: # body.append('<span class="label label-inverse">Pillbox</span>') body.append('<img src="%spact/icons/bucket.png">' % settings.STATIC_URL) elif obs.method == DOT_OBSERVATION_SELF: # body.append('<span class="label">Self</span>') body.append('<img src="%spact/icons/minus.png">' % settings.STATIC_URL) body.append(' </div> <!-- close time-cell -->') #close time-cell # body.append(' </div>') #close observation else: #empty observations for this dose_num body.append('<div class="time-label">Dose %d</div>' % (int(dose_num) + 1)) body.append('<div class="time-cell">') body.append('<div class="observation">') body.append("empty! </div>") # body.append(' </div>') body.append(' </div> <!-- close observation -->') #close observation body.append(' </div> <!-- close calendar cell -->') # close calendar-cell if len(day_notes) > 0 : body.append('<div class="date-notes-block">') body.append('<i class="icon-info-sign"></i> ') body.append('<small>%s</small>' % ('<br>'.join(day_notes))) body.append('</div> <!-- end notes -->') return self.day_cell(cssclass, '%d %s' % (day, ''.join(body))) if weekday < 5 and not future: missing_link = [] return self.day_cell(cssclass, "%d %s" % (day, ''.join(missing_link))) elif weekday < 5 and future: return self.day_cell('future', "%d" % day) else: return self.day_cell(cssclass, day) return self.day_cell('noday', ' ')