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

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

We have to call notify(grok.ObjectModifiedEvent?(self)) to update the catalog when only an attribute is changed.

Only one bed per student is allowed.

  • Property svn:keywords set to Id
File size: 10.7 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)
36
37class HostelsContainerTestCase(FunctionalTestCase):
38
39    layer = FunctionalLayer
40
41    def test_interfaces(self):
42        # Make sure the correct interfaces are implemented.
43        self.assertTrue(
44            verifyClass(
45                IHostelsContainer, HostelsContainer)
46            )
47        self.assertTrue(
48            verifyObject(
49                IHostelsContainer, HostelsContainer())
50            )
51        self.assertTrue(
52            verifyClass(
53                IHostel, Hostel)
54            )
55        self.assertTrue(
56            verifyObject(
57                IHostel, Hostel())
58            )
59        self.assertTrue(
60            verifyClass(
61                IBed, Bed)
62            )
63        self.assertTrue(
64            verifyObject(
65                IBed, Bed())
66            )
67        return
68
69    def test_base(self):
70        # We cannot call the fundamental methods of a base in that case
71        container = HostelsContainer()
72        self.assertRaises(
73            NotImplementedError, container.archive)
74        self.assertRaises(
75            NotImplementedError, container.clear)
76
77class HostelsFullSetup(FunctionalTestCase):
78
79    def setUp(self):
80        super(HostelsFullSetup, self).setUp()
81
82        # Setup a sample site for each test
83        app = University()
84        self.dc_root = tempfile.mkdtemp()
85        app['datacenter'].setStoragePath(self.dc_root)
86
87        # Prepopulate the ZODB...
88        self.getRootFolder()['app'] = app
89        # we add the site immediately after creation to the
90        # ZODB. Catalogs and other local utilities are not setup
91        # before that step.
92        self.app = self.getRootFolder()['app']
93        # Set site here. Some of the following setup code might need
94        # to access grok.getSite() and should get our new app then
95        setSite(app)
96
97        # Create a hostel
98        hostel = Hostel()
99        hostel.hostel_id = u'hall-x'
100        self.app['hostels'][hostel.hostel_id] = hostel
101
102        # Create a bed
103        bed = Bed()
104        bed.bed_id = u'xyz'
105        bed.bed_number = 1
106        bed.bed_type = u'abc'
107        self.app['hostels'][hostel.hostel_id][bed.bed_id] = bed
108
109        self.container_path = 'http://localhost/app/hostels'
110        self.manage_container_path = self.container_path + '/@@manage'
111        self.add_hostel_path = self.container_path + '/addhostel'
112
113        # Put the prepopulated site into test ZODB and prepare test
114        # browser
115        self.browser = Browser()
116        self.browser.handleErrors = False
117
118    def tearDown(self):
119        super(HostelsFullSetup, self).tearDown()
120        clearSite()
121        shutil.rmtree(self.dc_root)
122
123class BedCatalogTests(HostelsFullSetup):
124
125    layer = FunctionalLayer
126
127    def test_get_catalog(self):
128        # We can get an students catalog if we wish
129        cat = queryUtility(ICatalog, name='beds_catalog')
130        assert cat is not None
131
132    def test_search_by_type(self):
133        # We can find a certain bed
134        cat = queryUtility(ICatalog, name='beds_catalog')
135        results = cat.searchResults(bed_type=(u'abc', u'abc'))
136        results = [x for x in results] # Turn results generator into list
137        assert len(results) == 1
138        assert results[0] is self.app['hostels']['hall-x']['xyz']
139
140    def test_search_by_owner(self):
141        # We can find a certain bed
142        myobj = self.app['hostels']['hall-x']['xyz']
143        myobj.owner = u'abc'
144        notify(grok.ObjectModifiedEvent(myobj))
145        cat = queryUtility(ICatalog, name='beds_catalog')
146        results = cat.searchResults(owner=(u'abc', u'abc'))
147        results = [x for x in results] # Turn results generator into list
148        assert len(results) == 1
149        assert results[0] is self.app['hostels']['hall-x']['xyz']
150
151class HostelsUITests(HostelsFullSetup):
152
153    layer = FunctionalLayer
154
155    def test_anonymous_access(self):
156        # Anonymous users can't access hostels containers
157        self.assertRaises(
158            Unauthorized, self.browser.open, self.manage_container_path)
159        return
160
161    def test_add_search_edit_delete_manage_hostels(self):
162        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
163        self.browser.open(self.container_path)
164        self.browser.getLink("Manage accommodation").click()
165        self.assertEqual(self.browser.headers['Status'], '200 Ok')
166        self.assertEqual(self.browser.url, self.manage_container_path)
167        self.browser.getControl("Add hostel").click()
168        self.assertEqual(self.browser.headers['Status'], '200 Ok')
169        self.assertEqual(self.browser.url, self.add_hostel_path)
170        self.browser.getControl("Create hostel").click()
171        self.assertEqual(self.browser.headers['Status'], '200 Ok')
172        self.assertTrue('Hostel created' in self.browser.contents)
173        self.browser.open(self.container_path + '/addhostel')
174        self.browser.getControl("Create hostel").click()
175        self.assertTrue('The hostel already exists' in self.browser.contents)
176        hall = self.app['hostels']['hall-1']
177        hall.blocks_for_female = ['A','B']
178        self.browser.open(self.container_path + '/hall-1')
179        expected = '''...<ul id="form.blocks_for_female" ><li>Block A</li>
180<li>Block B</li></ul>...'''
181        self.assertMatches(expected,self.browser.contents)
182        self.browser.open(self.container_path + '/hall-1/manage')
183        self.browser.getControl(name="form.rooms_per_floor").value = '1'
184        self.browser.getControl("Save").click()
185        self.assertTrue('Form has been saved' in self.browser.contents)
186        # Since the testbrowser does not support Javascrip the
187        # save action cleared the settings above and we have to set them
188        # again
189        self.assertTrue(len(hall.blocks_for_female) == 0)
190        hall.blocks_for_female = ['A','B']
191        hall.beds_for_fresh = ['A']
192        hall.beds_for_returning = ['B']
193        hall.beds_for_final = ['C']
194        hall.beds_for_all = ['D','E']
195        self.browser.getControl("Update all beds").click()
196        expected = '...0 empty beds removed, 10 beds added, 0 occupied beds modified ()...'
197        self.assertMatches(expected,self.browser.contents)
198        cat = queryUtility(ICatalog, name='beds_catalog')
199        results = cat.searchResults(
200            bed_type=('regular_female_all', 'regular_female_all'))
201        results = [x for x in results]
202        assert len(results) == 4
203        # Reserve bed
204        self.browser.getControl("Switch reservation", index=0).click()
205        self.assertTrue('No item selected' in self.browser.contents)
206        ctrl = self.browser.getControl(name='val_id')
207        ctrl.getControl(value='hall-1_A_101_A').selected = True
208        ctrl.getControl(value='hall-1_A_101_B').selected = True
209        ctrl.getControl(value='hall-1_A_101_C').selected = True
210        ctrl.getControl(value='hall-1_A_101_D').selected = True
211        self.browser.getControl("Switch reservation", index=0).click()
212        self.assertTrue('Successfully switched beds: hall-1_A_101_A (reserved)'
213            in self.browser.contents)
214        assert self.app['hostels']['hall-1'][
215            'hall-1_A_101_D'].bed_type == 'regular_female_reserved'
216        expected = 'name="form.beds_reserved.0." size="20" type="text" value="A_101_A"  />'
217        self.assertTrue(expected in self.browser.contents)
218        # Provoke exception
219        self.app['hostels']['hall-1']['hall-1_A_101_D'].bed_type = u'nonsense'
220        ctrl = self.browser.getControl(name='val_id')
221        ctrl.getControl(value='hall-1_A_101_D').selected = True
222        self.browser.getControl("Switch reservation", index=0).click()
223        self.assertMatches(
224            '...need more than 1 value to unpack...', self.browser.contents)
225        self.app['hostels']['hall-1'][
226            'hall-1_A_101_D'].bed_type = u'regular_female_reserved'
227        # Change hostel configuration
228        hall.beds_for_all = ['D']
229        self.browser.getControl("Update all beds").click()
230        expected = '...10 empty beds removed, 8 beds added, 0 occupied beds modified...'
231        self.assertMatches(expected,self.browser.contents)
232        results = cat.searchResults(
233            bed_type=('regular_female_all', 'regular_female_all'))
234        results = [x for x in results]
235        assert len(results) == 1
236        # Unreserve bed
237        ctrl = self.browser.getControl(name='val_id')
238        ctrl.getControl(value='hall-1_A_101_A').selected = True
239        ctrl.getControl(value='hall-1_A_101_B').selected = True
240        ctrl.getControl(value='hall-1_A_101_C').selected = True
241        ctrl.getControl(value='hall-1_A_101_D').selected = True
242        self.browser.getControl("Switch reservation", index=0).click()
243        assert self.app['hostels']['hall-1'][
244            'hall-1_A_101_D'].bed_type == 'regular_female_all'
245        self.assertFalse(expected in self.browser.contents)
246        # Remove entire hostel
247        self.browser.open(self.manage_container_path)
248        ctrl = self.browser.getControl(name='val_id')
249        value = ctrl.options[0]
250        ctrl.getControl(value=value).selected = True
251        self.browser.getControl("Remove selected", index=0).click()
252        self.assertTrue('Successfully removed' in self.browser.contents)
253        # Catalog is empty
254        results = cat.searchResults(
255            bed_type=('regular_female_all', 'regular_female_all'))
256        results = [x for x in results]
257        assert len(results) == 0
Note: See TracBrowser for help on using the repository browser.