2 from BeautifulSoup import BeautifulSoup
6 import simplejson as json
9 from django.core import mail
10 from django.core.exceptions import ObjectDoesNotExist
11 from django.test import TestCase
12 from htsworkflow.frontend.experiments import models
13 from htsworkflow.frontend.experiments import experiments
14 from htsworkflow.frontend.auth import apidata
18 class ExperimentsTestCases(TestCase):
19 fixtures = ['test_flowcells.json']
24 def test_flowcell_information(self):
26 Check the code that packs the django objects into simple types.
28 for fc_id in [u'303TUAAXX', u"42JTNAAXX", "42JU1AAXX"]:
29 fc_dict = experiments.flowcell_information(fc_id)
30 fc_django = models.FlowCell.objects.get(flowcell_id=fc_id)
31 self.failUnlessEqual(fc_dict['flowcell_id'], fc_id)
32 self.failUnlessEqual(fc_django.flowcell_id, fc_id)
33 self.failUnlessEqual(fc_dict['sequencer'], fc_django.sequencer.name)
34 self.failUnlessEqual(fc_dict['read_length'], fc_django.read_length)
35 self.failUnlessEqual(fc_dict['notes'], fc_django.notes)
36 self.failUnlessEqual(fc_dict['cluster_station'], fc_django.cluster_station.name)
38 for lane in fc_django.lane_set.all():
39 lane_dict = fc_dict['lane_set'][lane.lane_number]
40 self.failUnlessEqual(lane_dict['cluster_estimate'], lane.cluster_estimate)
41 self.failUnlessEqual(lane_dict['comment'], lane.comment)
42 self.failUnlessEqual(lane_dict['flowcell'], lane.flowcell.flowcell_id)
43 self.failUnlessEqual(lane_dict['lane_number'], lane.lane_number)
44 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
45 self.failUnlessEqual(lane_dict['library_id'], lane.library.id)
46 self.failUnlessAlmostEqual(float(lane_dict['pM']), float(lane.pM))
47 self.failUnlessEqual(lane_dict['library_species'],
48 lane.library.library_species.scientific_name)
50 response = self.client.get('/experiments/config/%s/json' % (fc_id,), apidata)
51 # strptime isoformat string = '%Y-%m-%dT%H:%M:%S'
52 fc_json = json.loads(response.content)
53 self.failUnlessEqual(fc_json['flowcell_id'], fc_id)
54 self.failUnlessEqual(fc_json['sequencer'], fc_django.sequencer.name)
55 self.failUnlessEqual(fc_json['read_length'], fc_django.read_length)
56 self.failUnlessEqual(fc_json['notes'], fc_django.notes)
57 self.failUnlessEqual(fc_json['cluster_station'], fc_django.cluster_station.name)
60 for lane in fc_django.lane_set.all():
61 lane_dict = fc_json['lane_set'][unicode(lane.lane_number)]
62 self.failUnlessEqual(lane_dict['cluster_estimate'], lane.cluster_estimate)
63 self.failUnlessEqual(lane_dict['comment'], lane.comment)
64 self.failUnlessEqual(lane_dict['flowcell'], lane.flowcell.flowcell_id)
65 self.failUnlessEqual(lane_dict['lane_number'], lane.lane_number)
66 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
67 self.failUnlessEqual(lane_dict['library_id'], lane.library.id)
68 self.failUnlessAlmostEqual(float(lane_dict['pM']), float(lane.pM))
69 self.failUnlessEqual(lane_dict['library_species'],
70 lane.library.library_species.scientific_name)
72 def test_invalid_flowcell(self):
74 Make sure we get a 404 if we request an invalid flowcell ID
76 response = self.client.get('/experiments/config/nottheone/json', apidata)
77 self.failUnlessEqual(response.status_code, 404)
79 def test_no_key(self):
81 Require logging in to retrieve meta data
83 response = self.client.get(u'/experiments/config/303TUAAXX/json')
84 self.failUnlessEqual(response.status_code, 403)
86 def test_library_id(self):
88 Library IDs should be flexible, so make sure we can retrive a non-numeric ID
90 response = self.client.get('/experiments/config/303TUAAXX/json', apidata)
91 self.failUnlessEqual(response.status_code, 200)
92 flowcell = json.loads(response.content)
94 self.failUnlessEqual(flowcell['lane_set']['3']['library_id'], 'SL039')
96 response = self.client.get('/samples/library/SL039/json', apidata)
97 self.failUnlessEqual(response.status_code, 200)
98 library_sl039 = json.loads(response.content)
100 self.failUnlessEqual(library_sl039['library_id'], 'SL039')
102 def test_raw_id_field(self):
106 Library's have IDs, libraries also have primary keys,
107 we eventually had enough libraries that the drop down combo box was too
108 hard to filter through, unfortnately we want a field that uses our library
109 id and not the internal primary key, and raw_id_field uses primary keys.
111 This tests to make sure that the value entered in the raw library id field matches
112 the library id looked up.
114 expected_ids = [u'10981',u'11016',u'SL039',u'11060',
115 u'11061',u'11062',u'11063',u'11064']
116 self.client.login(username='supertest', password='BJOKL5kAj6aFZ6A5')
117 response = self.client.get('/admin/experiments/flowcell/153/')
118 soup = BeautifulSoup(response.content)
120 input_field = soup.find(id='id_lane_set-%d-library' % (i,))
121 library_field = input_field.findNext('strong')
122 library_id, library_name = library_field.string.split(':')
123 # strip leading '#' sign from name
124 library_id = library_id[1:]
125 self.failUnlessEqual(library_id, expected_ids[i])
126 self.failUnlessEqual(input_field['value'], library_id)
128 def test_lanes_for(self):
130 Check the code that packs the django objects into simple types.
133 lanes = experiments.lanes_for(user)
134 self.failUnlessEqual(len(lanes), 5)
136 response = self.client.get('/experiments/lanes_for/%s/json' % (user,), apidata)
137 lanes_json = json.loads(response.content)
138 self.failUnlessEqual(len(lanes), len(lanes_json))
139 for i in range(len(lanes)):
140 self.failUnlessEqual(lanes[i]['comment'], lanes_json[i]['comment'])
141 self.failUnlessEqual(lanes[i]['lane_number'], lanes_json[i]['lane_number'])
142 self.failUnlessEqual(lanes[i]['flowcell'], lanes_json[i]['flowcell'])
143 self.failUnlessEqual(lanes[i]['run_date'], lanes_json[i]['run_date'])
145 def test_lanes_for_no_lanes(self):
147 Do we get something meaningful back when the user isn't attached to anything?
150 lanes = experiments.lanes_for(user)
151 self.failUnlessEqual(len(lanes), 0)
153 response = self.client.get('/experiments/lanes_for/%s/json' % (user,), apidata)
154 lanes_json = json.loads(response.content)
156 def test_lanes_for_no_user(self):
158 Do we get something meaningful back when its the wrong user
160 user = 'not a real user'
161 self.failUnlessRaises(ObjectDoesNotExist, experiments.lanes_for, user)
163 response = self.client.get('/experiments/lanes_for/%s/json' % (user,), apidata)
164 self.failUnlessEqual(response.status_code, 404)
167 class TestEmailNotify(TestCase):
168 fixtures = ['test_flowcells.json']
170 def test_started_email_not_logged_in(self):
171 response = self.client.get('/experiments/started/153/')
172 self.failUnlessEqual(response.status_code, 302)
174 def test_started_email_logged_in_user(self):
175 self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
176 response = self.client.get('/experiments/started/153/')
177 self.failUnlessEqual(response.status_code, 302)
179 def test_started_email_logged_in_staff(self):
180 self.client.login(username='admintest', password='BJOKL5kAj6aFZ6A5')
181 response = self.client.get('/experiments/started/153/')
182 self.failUnlessEqual(response.status_code, 200)
184 def test_started_email_send(self):
185 self.client.login(username='admintest', password='BJOKL5kAj6aFZ6A5')
186 response = self.client.get('/experiments/started/153/')
187 self.failUnlessEqual(response.status_code, 200)
189 self.failUnless('pk1@example.com' in response.content)
190 self.failUnless('Lane #8 : (11064) Paired ends 104' in response.content)
192 response = self.client.get('/experiments/started/153/', {'send':'1','bcc':'on'})
193 self.failUnlessEqual(response.status_code, 200)
194 self.failUnlessEqual(len(mail.outbox), 4)
195 for m in mail.outbox:
196 self.failUnless(len(m.body) > 0)
198 def test_email_navigation(self):
200 Can we navigate between the flowcell and email forms properly?
202 self.client.login(username='supertest', password='BJOKL5kAj6aFZ6A5')
203 response = self.client.get('/experiments/started/153/')
204 self.failUnlessEqual(response.status_code, 200)
205 self.failUnless(re.search('Flowcell 303TUAAXX', response.content))
206 # require that navigation back to the admin page exists
207 self.failUnless(re.search('<a href="/admin/experiments/flowcell/153/">[^<]+</a>', response.content))