source: main/waeup.sirp/trunk/src/waeup/sirp/hostels/tests.py @ 7045

Last change on this file since 7045 was 7045, checked in by Henrik Bettermann, 13 years ago

Add test for bed release.

  • Property svn:keywords set to Id
File size: 12.1 KB
Line 
1## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
2## This program is free software; you can redistribute it and/or modify
3## it under the terms of the GNU General Public License as published by
4## the Free Software Foundation; either version 2 of the License, or
5## (at your option) any later version.
6##
7## This program is distributed in the hope that it will be useful,
8## but WITHOUT ANY WARRANTY; without even the implied warranty of
9## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10## GNU General Public License for more details.
11##
12## You should have received a copy of the GNU General Public License
13## along with this program; if not, write to the Free Software
14## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15##
16"""
17Tests for hostels and their UI components.
18"""
19import shutil
20import tempfile
21import grok
22from zope.event import notify
23
24from zope.interface.verify import verifyClass, verifyObject
25from zope.component.hooks import setSite, clearSite
26from zope.testbrowser.testing import Browser
27from zope.security.interfaces import Unauthorized
28from zope.catalog.interfaces import ICatalog
29from zope.component import queryUtility
30from waeup.sirp.app import University
31from waeup.sirp.hostels.interfaces import (
32    IHostelsContainer, IHostel, IBed)
33from waeup.sirp.hostels.container import HostelsContainer
34from waeup.sirp.hostels.hostel import Hostel, Bed
35from waeup.sirp.testing import (FunctionalLayer, FunctionalTestCase)
36from waeup.sirp.students.student import Student
37from waeup.sirp.students.accommodation import BedTicket
38
39class HostelsContainerTestCase(FunctionalTestCase):
40
41    layer = FunctionalLayer
42
43    def test_interfaces(self):
44        # Make sure the correct interfaces are implemented.
45        self.assertTrue(
46            verifyClass(
47                IHostelsContainer, HostelsContainer)
48            )
49        self.assertTrue(
50            verifyObject(
51                IHostelsContainer, HostelsContainer())
52            )
53        self.assertTrue(
54            verifyClass(
55                IHostel, Hostel)
56            )
57        self.assertTrue(
58            verifyObject(
59                IHostel, Hostel())
60            )
61        self.assertTrue(
62            verifyClass(
63                IBed, Bed)
64            )
65        self.assertTrue(
66            verifyObject(
67                IBed, Bed())
68            )
69        return
70
71    def test_base(self):
72        # We cannot call the fundamental methods of a base in that case
73        container = HostelsContainer()
74        self.assertRaises(
75            NotImplementedError, container.archive)
76        self.assertRaises(
77            NotImplementedError, container.clear)
78
79class HostelsFullSetup(FunctionalTestCase):
80
81    def setUp(self):
82        super(HostelsFullSetup, self).setUp()
83
84        # Setup a sample site for each test
85        app = University()
86        self.dc_root = tempfile.mkdtemp()
87        app['datacenter'].setStoragePath(self.dc_root)
88
89        # Prepopulate the ZODB...
90        self.getRootFolder()['app'] = app
91        # we add the site immediately after creation to the
92        # ZODB. Catalogs and other local utilities are not setup
93        # before that step.
94        self.app = self.getRootFolder()['app']
95        # Set site here. Some of the following setup code might need
96        # to access grok.getSite() and should get our new app then
97        setSite(app)
98
99        # Add student with subobjects
100        student = Student()
101        student.fullname = u'Anna Tester'
102        student.reg_number = u'123'
103        student.matric_number = u'234'
104        student.sex = u'f'
105        self.app['students'].addStudent(student)
106        self.student_id = student.student_id
107        self.student = self.app['students'][self.student_id]
108        self.student['studycourse'].current_session = 2004
109        self.student['studycourse'].entry_session = 2004
110
111        # Set accommodation_session
112        self.app['configuration'].accommodation_session = 2004
113
114        # Create a hostel
115        hostel = Hostel()
116        hostel.hostel_id = u'hall-x'
117        self.app['hostels'][hostel.hostel_id] = hostel
118
119        # Create a bed
120        bed = Bed()
121        bed.bed_id = u'xyz'
122        bed.bed_number = 1
123        bed.bed_type = u'abc'
124        self.app['hostels'][hostel.hostel_id][bed.bed_id] = bed
125
126        self.container_path = 'http://localhost/app/hostels'
127        self.manage_container_path = self.container_path + '/@@manage'
128        self.add_hostel_path = self.container_path + '/addhostel'
129
130        # Put the prepopulated site into test ZODB and prepare test
131        # browser
132        self.browser = Browser()
133        self.browser.handleErrors = False
134
135    def tearDown(self):
136        super(HostelsFullSetup, self).tearDown()
137        clearSite()
138        shutil.rmtree(self.dc_root)
139
140class BedCatalogTests(HostelsFullSetup):
141
142    layer = FunctionalLayer
143
144    def test_get_catalog(self):
145        # We can get a beds catalog if we wish
146        cat = queryUtility(ICatalog, name='beds_catalog')
147        assert cat is not None
148
149    def test_search_by_type(self):
150        # We can find a certain bed
151        cat = queryUtility(ICatalog, name='beds_catalog')
152        results = cat.searchResults(bed_type=(u'abc', u'abc'))
153        results = [x for x in results] # Turn results generator into list
154        assert len(results) == 1
155        assert results[0] is self.app['hostels']['hall-x']['xyz']
156
157    def test_search_by_owner(self):
158        # We can find a certain bed
159        myobj = self.app['hostels']['hall-x']['xyz']
160        myobj.owner = u'abc'
161        notify(grok.ObjectModifiedEvent(myobj))
162        cat = queryUtility(ICatalog, name='beds_catalog')
163        results = cat.searchResults(owner=(u'abc', u'abc'))
164        results = [x for x in results] # Turn results generator into list
165        assert len(results) == 1
166        assert results[0] is self.app['hostels']['hall-x']['xyz']
167
168class HostelsUITests(HostelsFullSetup):
169
170    layer = FunctionalLayer
171
172    def test_anonymous_access(self):
173        # Anonymous users can't access hostels containers
174        self.assertRaises(
175            Unauthorized, self.browser.open, self.manage_container_path)
176        return
177
178    def test_add_search_edit_delete_manage_hostels(self):
179        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
180        self.browser.open(self.container_path)
181        self.browser.getLink("Manage accommodation").click()
182        self.assertEqual(self.browser.headers['Status'], '200 Ok')
183        self.assertEqual(self.browser.url, self.manage_container_path)
184        self.browser.getControl("Add hostel").click()
185        self.assertEqual(self.browser.headers['Status'], '200 Ok')
186        self.assertEqual(self.browser.url, self.add_hostel_path)
187        self.browser.getControl("Create hostel").click()
188        self.assertEqual(self.browser.headers['Status'], '200 Ok')
189        self.assertTrue('Hostel created' in self.browser.contents)
190        self.browser.open(self.container_path + '/addhostel')
191        self.browser.getControl("Create hostel").click()
192        self.assertTrue('The hostel already exists' in self.browser.contents)
193        hall = self.app['hostels']['hall-1']
194        hall.blocks_for_female = ['A','B']
195        self.browser.open(self.container_path + '/hall-1')
196        expected = '''...<ul id="form.blocks_for_female" ><li>Block A</li>
197<li>Block B</li></ul>...'''
198        self.assertMatches(expected,self.browser.contents)
199        self.browser.open(self.container_path + '/hall-1/manage')
200        self.browser.getControl(name="form.rooms_per_floor").value = '1'
201        self.browser.getControl("Save").click()
202        self.assertTrue('Form has been saved' in self.browser.contents)
203        # Since the testbrowser does not support Javascrip the
204        # save action cleared the settings above and we have to set them
205        # again
206        self.assertTrue(len(hall.blocks_for_female) == 0)
207        hall.blocks_for_female = ['A','B']
208        hall.beds_for_fresh = ['A']
209        hall.beds_for_returning = ['B']
210        hall.beds_for_final = ['C']
211        hall.beds_for_all = ['D','E']
212        self.browser.getControl("Update all beds").click()
213        expected = '...0 empty beds removed, 10 beds added, 0 occupied beds modified ()...'
214        self.assertMatches(expected,self.browser.contents)
215        cat = queryUtility(ICatalog, name='beds_catalog')
216        results = cat.searchResults(
217            bed_type=('regular_female_all', 'regular_female_all'))
218        results = [x for x in results]
219        assert len(results) == 4
220        # Reserve bed
221        self.browser.getControl("Switch reservation", index=0).click()
222        self.assertTrue('No item selected' in self.browser.contents)
223        ctrl = self.browser.getControl(name='val_id')
224        ctrl.getControl(value='hall-1_A_101_A').selected = True
225        ctrl.getControl(value='hall-1_A_101_B').selected = True
226        ctrl.getControl(value='hall-1_A_101_C').selected = True
227        ctrl.getControl(value='hall-1_A_101_D').selected = True
228        self.browser.getControl("Switch reservation", index=0).click()
229        self.assertTrue('Successfully switched beds: hall-1_A_101_A (reserved)'
230            in self.browser.contents)
231        assert self.app['hostels']['hall-1'][
232            'hall-1_A_101_D'].bed_type == 'regular_female_reserved'
233        expected = 'name="form.beds_reserved.0." size="20" type="text" value="A_101_A"  />'
234        self.assertTrue(expected in self.browser.contents)
235        # Provoke exception
236        self.app['hostels']['hall-1']['hall-1_A_101_D'].bed_type = u'nonsense'
237        ctrl = self.browser.getControl(name='val_id')
238        ctrl.getControl(value='hall-1_A_101_D').selected = True
239        self.browser.getControl("Switch reservation", index=0).click()
240        self.assertMatches(
241            '...need more than 1 value to unpack...', self.browser.contents)
242        self.app['hostels']['hall-1'][
243            'hall-1_A_101_D'].bed_type = u'regular_female_reserved'
244        # Change hostel configuration
245        hall.beds_for_all = ['D']
246        self.browser.getControl("Update all beds").click()
247        expected = '...10 empty beds removed, 8 beds added, 0 occupied beds modified...'
248        self.assertMatches(expected,self.browser.contents)
249        results = cat.searchResults(
250            bed_type=('regular_female_all', 'regular_female_all'))
251        results = [x for x in results]
252        assert len(results) == 1
253        # Unreserve bed
254        ctrl = self.browser.getControl(name='val_id')
255        ctrl.getControl(value='hall-1_A_101_A').selected = True
256        ctrl.getControl(value='hall-1_A_101_B').selected = True
257        ctrl.getControl(value='hall-1_A_101_C').selected = True
258        ctrl.getControl(value='hall-1_A_101_D').selected = True
259        self.browser.getControl("Switch reservation", index=0).click()
260        assert self.app['hostels']['hall-1'][
261            'hall-1_A_101_D'].bed_type == 'regular_female_all'
262        self.assertFalse(expected in self.browser.contents)
263        # Release bed which has previously been booked
264        bedticket = BedTicket()
265        bedticket.ticket_id = u'2004'
266        bedticket.bed_coordinates = u'anything'
267        self.student['accommodation'].addBedTicket(bedticket)
268        self.app['hostels']['hall-1']['hall-1_A_101_D'].owner = self.student_id
269        self.browser.open(self.container_path + '/hall-1/manage')
270        ctrl = self.browser.getControl(name='val_id')
271        ctrl.getControl(value='hall-1_A_101_D').selected = True
272        self.browser.getControl("Release selected beds", index=0).click()
273        self.assertMatches(
274          '...Successfully released beds: hall-1_A_101_D (%s)...' % self.student_id,
275          self.browser.contents)
276        self.assertMatches(bedticket.bed_coordinates,
277          u' -- booking cancelled on <YYYY-MM-DD hh:mm:ss> --')
278        # Remove entire hostel
279        self.browser.open(self.manage_container_path)
280        ctrl = self.browser.getControl(name='val_id')
281        value = ctrl.options[0]
282        ctrl.getControl(value=value).selected = True
283        self.browser.getControl("Remove selected", index=0).click()
284        self.assertTrue('Successfully removed' in self.browser.contents)
285        # Catalog is empty
286        results = cat.searchResults(
287            bed_type=('regular_female_all', 'regular_female_all'))
288        results = [x for x in results]
289        assert len(results) == 0
Note: See TracBrowser for help on using the repository browser.