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

Last change on this file since 7058 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
RevLine 
[6951]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"""
[6988]17Tests for hostels and their UI components.
[6951]18"""
[6961]19import shutil
20import tempfile
[7003]21import grok
22from zope.event import notify
23
[6951]24from zope.interface.verify import verifyClass, verifyObject
[6961]25from zope.component.hooks import setSite, clearSite
26from zope.testbrowser.testing import Browser
27from zope.security.interfaces import Unauthorized
[6972]28from zope.catalog.interfaces import ICatalog
29from zope.component import queryUtility
[6961]30from waeup.sirp.app import University
[6951]31from waeup.sirp.hostels.interfaces import (
[6963]32    IHostelsContainer, IHostel, IBed)
[6951]33from waeup.sirp.hostels.container import HostelsContainer
[6963]34from waeup.sirp.hostels.hostel import Hostel, Bed
[6951]35from waeup.sirp.testing import (FunctionalLayer, FunctionalTestCase)
[7045]36from waeup.sirp.students.student import Student
37from waeup.sirp.students.accommodation import BedTicket
[6951]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            )
[6963]61        self.assertTrue(
62            verifyClass(
63                IBed, Bed)
64            )
65        self.assertTrue(
66            verifyObject(
67                IBed, Bed())
68            )
[6951]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)
[6961]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
[7045]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
[6972]114        # Create a hostel
115        hostel = Hostel()
[6973]116        hostel.hostel_id = u'hall-x'
[6972]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
[6961]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
[6972]140class BedCatalogTests(HostelsFullSetup):
141
142    layer = FunctionalLayer
143
144    def test_get_catalog(self):
[7045]145        # We can get a beds catalog if we wish
[6972]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')
[7003]152        results = cat.searchResults(bed_type=(u'abc', u'abc'))
[6972]153        results = [x for x in results] # Turn results generator into list
154        assert len(results) == 1
[6973]155        assert results[0] is self.app['hostels']['hall-x']['xyz']
[6972]156
[7003]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
[6961]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
[6985]178    def test_add_search_edit_delete_manage_hostels(self):
[6961]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)
[6988]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)
[6973]193        hall = self.app['hostels']['hall-1']
[6961]194        hall.blocks_for_female = ['A','B']
[6973]195        self.browser.open(self.container_path + '/hall-1')
[6961]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)
[6973]199        self.browser.open(self.container_path + '/hall-1/manage')
[6985]200        self.browser.getControl(name="form.rooms_per_floor").value = '1'
[6962]201        self.browser.getControl("Save").click()
202        self.assertTrue('Form has been saved' in self.browser.contents)
[6985]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']
[6988]208        hall.beds_for_fresh = ['A']
209        hall.beds_for_returning = ['B']
210        hall.beds_for_final = ['C']
[6985]211        hall.beds_for_all = ['D','E']
212        self.browser.getControl("Update all beds").click()
[6988]213        expected = '...0 empty beds removed, 10 beds added, 0 occupied beds modified ()...'
[6985]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
[6988]220        # Reserve bed
221        self.browser.getControl("Switch reservation", index=0).click()
222        self.assertTrue('No item selected' in self.browser.contents)
[6985]223        ctrl = self.browser.getControl(name='val_id')
[6988]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
[6985]227        ctrl.getControl(value='hall-1_A_101_D').selected = True
228        self.browser.getControl("Switch reservation", index=0).click()
[6988]229        self.assertTrue('Successfully switched beds: hall-1_A_101_A (reserved)'
[6985]230            in self.browser.contents)
[6988]231        assert self.app['hostels']['hall-1'][
[6985]232            'hall-1_A_101_D'].bed_type == 'regular_female_reserved'
[6988]233        expected = 'name="form.beds_reserved.0." size="20" type="text" value="A_101_A"  />'
[6985]234        self.assertTrue(expected in self.browser.contents)
[6988]235        # Provoke exception
236        self.app['hostels']['hall-1']['hall-1_A_101_D'].bed_type = u'nonsense'
[6985]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()
[6988]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'
[6985]244        # Change hostel configuration
245        hall.beds_for_all = ['D']
246        self.browser.getControl("Update all beds").click()
[6988]247        expected = '...10 empty beds removed, 8 beds added, 0 occupied beds modified...'
[6985]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]
[6988]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)
[7045]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> --')
[6985]278        # Remove entire hostel
[6962]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)
[6985]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.