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