Turn the library_id back into the primary key for samples_library (SCHEMA CHANGE!)
[htsworkflow.git] / htsworkflow / frontend / experiments / tests.py
1 import re
2 from BeautifulSoup import BeautifulSoup
3 try:
4     import json
5 except ImportError, e:
6     import simplejson as json
7 import sys
8
9 from django.core import mail
10 from django.test import TestCase
11 from htsworkflow.frontend.experiments import models
12 from htsworkflow.frontend.experiments import experiments
13 from htsworkflow.frontend.auth import apidata
14
15 LANE_SET = range(1,9)
16
17 class ExperimentsTestCases(TestCase):
18     fixtures = ['test_flowcells.json']
19
20     def setUp(self):
21         pass
22
23     def test_flowcell_information(self):
24         """
25         Check the code that packs the django objects into simple types.
26         """
27         for fc_id in [u'303TUAAXX', u"42JTNAAXX", "42JU1AAXX"]:
28             fc_dict = experiments.flowcell_information(fc_id)
29             fc_django = models.FlowCell.objects.get(flowcell_id=fc_id)
30             self.failUnlessEqual(fc_dict['flowcell_id'], fc_id)
31             self.failUnlessEqual(fc_django.flowcell_id, fc_id)
32             self.failUnlessEqual(fc_dict['sequencer'], fc_django.sequencer.name)
33             self.failUnlessEqual(fc_dict['read_length'], fc_django.read_length)
34             self.failUnlessEqual(fc_dict['notes'], fc_django.notes)
35             self.failUnlessEqual(fc_dict['cluster_station'], fc_django.cluster_station.name)
36
37             for lane in fc_django.lane_set.all():
38                 lane_dict = fc_dict['lane_set'][lane.lane_number]
39                 self.failUnlessEqual(lane_dict['cluster_estimate'], lane.cluster_estimate)
40                 self.failUnlessEqual(lane_dict['comment'], lane.comment)
41                 self.failUnlessEqual(lane_dict['flowcell'], lane.flowcell.flowcell_id)
42                 self.failUnlessEqual(lane_dict['lane_number'], lane.lane_number)
43                 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
44                 self.failUnlessEqual(lane_dict['library_id'], lane.library.id)
45                 self.failUnlessAlmostEqual(lane_dict['pM'], float(lane.pM))
46                 self.failUnlessEqual(lane_dict['library_species'],
47                                      lane.library.library_species.scientific_name)
48                     
49             response = self.client.get('/experiments/config/%s/json' % (fc_id,), apidata)
50             # strptime isoformat string = '%Y-%m-%dT%H:%M:%S'
51             fc_json = json.loads(response.content)
52             self.failUnlessEqual(fc_json['flowcell_id'], fc_id)
53             self.failUnlessEqual(fc_json['sequencer'], fc_django.sequencer.name)
54             self.failUnlessEqual(fc_json['read_length'], fc_django.read_length)
55             self.failUnlessEqual(fc_json['notes'], fc_django.notes)
56             self.failUnlessEqual(fc_json['cluster_station'], fc_django.cluster_station.name)
57
58
59             for lane in fc_django.lane_set.all():
60                 lane_dict = fc_json['lane_set'][unicode(lane.lane_number)]
61                 self.failUnlessEqual(lane_dict['cluster_estimate'], lane.cluster_estimate)
62                 self.failUnlessEqual(lane_dict['comment'], lane.comment)
63                 self.failUnlessEqual(lane_dict['flowcell'], lane.flowcell.flowcell_id)
64                 self.failUnlessEqual(lane_dict['lane_number'], lane.lane_number)
65                 self.failUnlessEqual(lane_dict['library_name'], lane.library.library_name)
66                 self.failUnlessEqual(lane_dict['library_id'], lane.library.id)
67                 self.failUnlessAlmostEqual(lane_dict['pM'], float(lane.pM))
68                 self.failUnlessEqual(lane_dict['library_species'],
69                                      lane.library.library_species.scientific_name)
70
71     def test_invalid_flowcell(self):
72         """
73         Make sure we get a 404 if we request an invalid flowcell ID
74         """
75         response = self.client.get('/experiments/config/nottheone/json', apidata)
76         self.failUnlessEqual(response.status_code, 404)
77
78     def test_no_key(self):
79         """
80         Require logging in to retrieve meta data
81         """
82         response = self.client.get(u'/experiments/config/303TUAAXX/json')
83         self.failUnlessEqual(response.status_code, 403)
84
85     def test_library_id(self):
86         """
87         Library IDs should be flexible, so make sure we can retrive a non-numeric ID
88         """
89         response = self.client.get('/experiments/config/303TUAAXX/json', apidata)
90         self.failUnlessEqual(response.status_code, 200)
91         flowcell = json.loads(response.content)
92
93         self.failUnlessEqual(flowcell['lane_set']['3']['library_id'], 'SL039')
94
95         response = self.client.get('/samples/library/SL039/json', apidata)
96         self.failUnlessEqual(response.status_code, 200)
97         library_sl039 = json.loads(response.content)
98
99         self.failUnlessEqual(library_sl039['library_id'], 'SL039')
100
101     def test_raw_id_field(self):
102         """
103         Test ticket:147
104
105         Library's have IDs, libraries also have primary keys,
106         we eventually had enough libraries that the drop down combo box was too
107         hard to filter through, unfortnately we want a field that uses our library
108         id and not the internal primary key, and raw_id_field uses primary keys.
109
110         This tests to make sure that the value entered in the raw library id field matches
111         the library id looked up.
112         """
113         expected_ids = [u'10981',u'11016',u'SL039',u'11060',
114                         u'11061',u'11062',u'11063',u'11064']
115         self.client.login(username='supertest', password='BJOKL5kAj6aFZ6A5')
116         response = self.client.get('/admin/experiments/flowcell/153/')
117         soup = BeautifulSoup(response.content)
118         for i in range(0,8):
119             input_field = soup.find(id='id_lane_set-%d-library' % (i,))
120             library_field = input_field.findNext('strong')
121             library_id, library_name = library_field.string.split(':')
122             # strip leading '#' sign from name
123             library_id = library_id[1:]
124             self.failUnlessEqual(library_id, expected_ids[i])
125             self.failUnlessEqual(input_field['value'], library_id)
126
127 class TestEmailNotify(TestCase):
128     fixtures = ['test_flowcells.json']
129
130     def test_started_email_not_logged_in(self):
131         response = self.client.get('/experiments/started/153/')
132         self.failUnlessEqual(response.status_code, 302)
133
134     def test_started_email_logged_in_user(self):
135         self.client.login(username='test', password='BJOKL5kAj6aFZ6A5')
136         response = self.client.get('/experiments/started/153/')
137         self.failUnlessEqual(response.status_code, 302)
138         
139     def test_started_email_logged_in_staff(self):
140         self.client.login(username='admintest', password='BJOKL5kAj6aFZ6A5') 
141         response = self.client.get('/experiments/started/153/')
142         self.failUnlessEqual(response.status_code, 200)
143
144     def test_started_email_send(self):
145         self.client.login(username='admintest', password='BJOKL5kAj6aFZ6A5') 
146         response = self.client.get('/experiments/started/153/')
147         self.failUnlessEqual(response.status_code, 200)
148         
149         self.failUnless('pk1@example.com' in response.content)
150         self.failUnless('Lane #8 : (11064) Paired ends 104' in response.content)
151
152         response = self.client.get('/experiments/started/153/', {'send':'1','bcc':'on'})
153         self.failUnlessEqual(response.status_code, 200)
154         self.failUnlessEqual(len(mail.outbox), 4)
155         for m in mail.outbox:
156             self.failUnless(len(m.body) > 0)
157
158     def test_email_navigation(self):
159         """
160         Can we navigate between the flowcell and email forms properly?
161         """
162         self.client.login(username='supertest', password='BJOKL5kAj6aFZ6A5') 
163         response = self.client.get('/experiments/started/153/')
164         self.failUnlessEqual(response.status_code, 200)
165         self.failUnless(re.search('Flowcell 303TUAAXX', response.content))
166         # require that navigation back to the admin page exists
167         self.failUnless(re.search('<a href="/admin/experiments/flowcell/153/">[^<]+</a>', response.content))
168