source: main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py @ 13320

Last change on this file since 13320 was 13319, checked in by Henrik Bettermann, 9 years ago

Add page to release all expired allocations.

  • Property svn:keywords set to Id
File size: 26.3 KB
Line 
1## $Id: tests.py 13319 2015-10-14 17:07:35Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Tests for hostels and their UI components.
20"""
21import os
22import shutil
23import tempfile
24import grok
25import pytz
26from datetime import datetime, timedelta
27from zope.event import notify
28from zope.interface.verify import verifyClass, verifyObject
29from zope.component.hooks import setSite, clearSite
30from zope.testbrowser.testing import Browser
31from zope.security.interfaces import Unauthorized
32from zope.catalog.interfaces import ICatalog
33from zope.component import queryUtility
34from waeup.kofa.app import University
35from waeup.kofa.hostels.interfaces import (
36    IHostelsContainer, IHostel, IBed)
37from waeup.kofa.hostels.vocabularies import NOT_OCCUPIED
38from waeup.kofa.hostels.container import HostelsContainer
39from waeup.kofa.hostels.hostel import Hostel, Bed
40from waeup.kofa.hostels.batching import HostelProcessor
41from waeup.kofa.hostels.export import BedExporter, HostelExporter
42from waeup.kofa.testing import (FunctionalLayer, FunctionalTestCase)
43from waeup.kofa.students.student import Student
44from waeup.kofa.students.accommodation import BedTicket
45from waeup.kofa.university.department import Department
46
47HOSTEL_SAMPLE_DATA = open(
48    os.path.join(os.path.dirname(__file__), 'sample_hostel_data.csv'),
49    'rb').read()
50
51HOSTEL_HEADER_FIELDS = HOSTEL_SAMPLE_DATA.split(
52    '\n')[0].split(',')
53
54class HostelsContainerTestCase(FunctionalTestCase):
55
56    layer = FunctionalLayer
57
58    def test_interfaces(self):
59        # Make sure the correct interfaces are implemented.
60        self.assertTrue(
61            verifyClass(
62                IHostelsContainer, HostelsContainer)
63            )
64        self.assertTrue(
65            verifyObject(
66                IHostelsContainer, HostelsContainer())
67            )
68        self.assertTrue(
69            verifyClass(
70                IHostel, Hostel)
71            )
72        self.assertTrue(
73            verifyObject(
74                IHostel, Hostel())
75            )
76        self.assertTrue(
77            verifyClass(
78                IBed, Bed)
79            )
80        bed = Bed()
81        bed.bed_id = u'a_b_c_d'
82        bed.bed_type = u'a_b_c'
83        self.assertTrue(
84            verifyObject(
85                IBed, bed)
86            )
87        return
88
89    def test_base(self):
90        # We cannot call the fundamental methods of a base in that case
91        container = HostelsContainer()
92        hostel = Hostel()
93        # We cannot add arbitrary objects
94        department = Department()
95        self.assertRaises(
96            TypeError, container.addHostel, department)
97        self.assertRaises(
98            TypeError, hostel.addBed, department)
99        # Application is expired if startdate or enddate are not set
100        # or current datetime is outside application period.
101        self.assertTrue(container.expired)
102        delta = timedelta(days=10)
103        container.startdate = datetime.now(pytz.utc) - delta
104        self.assertTrue(container.expired)
105        container.enddate = datetime.now(pytz.utc) + delta
106        self.assertFalse(container.expired)
107
108class HostelsFullSetup(FunctionalTestCase):
109
110    def setUp(self):
111        super(HostelsFullSetup, self).setUp()
112
113        # Setup a sample site for each test
114        app = University()
115        self.dc_root = tempfile.mkdtemp()
116        app['datacenter'].setStoragePath(self.dc_root)
117
118        # Prepopulate the ZODB...
119        self.getRootFolder()['app'] = app
120        # we add the site immediately after creation to the
121        # ZODB. Catalogs and other local utilities are not setup
122        # before that step.
123        self.app = self.getRootFolder()['app']
124        # Set site here. Some of the following setup code might need
125        # to access grok.getSite() and should get our new app then
126        setSite(app)
127
128        # Add student with subobjects
129        student = Student()
130        student.firstname = u'Anna'
131        student.lastname = u'Tester'
132        student.reg_number = u'123'
133        student.matric_number = u'234'
134        student.sex = u'f'
135        self.app['students'].addStudent(student)
136        self.student_id = student.student_id
137        self.student = self.app['students'][self.student_id]
138        self.student['studycourse'].current_session = 2004
139        self.student['studycourse'].entry_session = 2004
140        # The students_catalog must be informed that the
141        # session attribute has changed
142        notify(grok.ObjectModifiedEvent(self.student))
143
144        # Set accommodation_session
145        self.app['hostels'].accommodation_session = 2004
146
147        # Create a hostel
148        hostel = Hostel()
149        hostel.hostel_id = u'hall-x'
150        self.app['hostels'][hostel.hostel_id] = hostel
151
152        # Create a bed
153        bed = Bed()
154        bed.bed_id = u'hall_block_room_bed'
155        bed.bed_number = 1
156        bed.bed_type = u'a_b_c'
157        self.app['hostels'][hostel.hostel_id][bed.bed_id] = bed
158
159        self.container_path = 'http://localhost/app/hostels'
160        self.student_path = 'http://localhost/app/students/%s' % self.student_id
161        self.manage_container_path = self.container_path + '/@@manage'
162        self.add_hostel_path = self.container_path + '/addhostel'
163
164        # Put the prepopulated site into test ZODB and prepare test
165        # browser
166        self.browser = Browser()
167        self.browser.handleErrors = False
168
169        self.logfile = os.path.join(
170            self.app['datacenter'].storage, 'logs', 'hostels.log')
171
172    def tearDown(self):
173        super(HostelsFullSetup, self).tearDown()
174        clearSite()
175        shutil.rmtree(self.dc_root)
176
177class HostelsContainerTests(HostelsFullSetup):
178
179    layer = FunctionalLayer
180
181    def test_release_expired_allocations(self):
182        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
183        cat = queryUtility(ICatalog, name='beds_catalog')
184        bedticket = BedTicket()
185        bedticket.booking_session = 2004
186        bedticket.bed_coordinates = u'anything'
187        self.student['accommodation'].addBedTicket(bedticket)
188        self.app[
189            'hostels']['hall-x']['hall_block_room_bed'].owner = self.student_id
190        notify(grok.ObjectModifiedEvent(
191            self.app['hostels']['hall-x']['hall_block_room_bed']))
192        results = cat.searchResults(owner=(self.student_id, self.student_id))
193        self.assertEqual(len(results), 1)
194        self.browser.open(self.container_path + '/releaseexpired')
195        self.assertTrue('No bed released' in self.browser.contents)
196        delta = timedelta(days=10)
197        bedticket.booking_date = datetime.utcnow() - delta
198        self.browser.open(self.container_path + '/releaseexpired')
199        self.assertTrue(
200            'Successfully released beds: hall_block_room_bed (K1000000)'
201            in self.browser.contents)
202        results = cat.searchResults(owner=(self.student_id, self.student_id))
203        self.assertEqual(len(results), 0)
204        self.assertMatches(bedticket.display_coordinates,
205            '-- booking expired (2015-10-14 08:35:38 UTC) --')
206        self.assertEqual(
207            self.app['hostels']['hall-x']['hall_block_room_bed'].owner,
208            NOT_OCCUPIED)
209        # Releasing is logged.
210        logcontent = open(self.logfile).read()
211        self.assertTrue(
212            'hostels.browser.ReleaseExpiredAllocationsPage - hostels - '
213            'released: hall_block_room_bed (K1000000)'
214            in logcontent)
215        return
216
217class BedCatalogTests(HostelsFullSetup):
218
219    layer = FunctionalLayer
220
221    def test_get_catalog(self):
222        # We can get a beds catalog if we wish
223        cat = queryUtility(ICatalog, name='beds_catalog')
224        assert cat is not None
225
226    def test_search_by_type(self):
227        # We can find a certain bed
228        cat = queryUtility(ICatalog, name='beds_catalog')
229        results = cat.searchResults(bed_type=(u'a_b_c', u'a_b_c'))
230        results = [x for x in results] # Turn results generator into list
231        assert len(results) == 1
232        assert results[0] is self.app['hostels']['hall-x']['hall_block_room_bed']
233
234    def test_search_by_owner(self):
235        # We can find a certain bed
236        myobj = self.app['hostels']['hall-x']['hall_block_room_bed']
237        myobj.owner = u'abc'
238        notify(grok.ObjectModifiedEvent(myobj))
239        cat = queryUtility(ICatalog, name='beds_catalog')
240        results = cat.searchResults(owner=(u'abc', u'abc'))
241        results = [x for x in results] # Turn results generator into list
242        assert len(results) == 1
243        assert results[0] is self.app['hostels']['hall-x']['hall_block_room_bed']
244
245class HostelsUITests(HostelsFullSetup):
246
247    layer = FunctionalLayer
248
249    def test_anonymous_access(self):
250        # Anonymous users can't access hostels containers
251        self.assertRaises(
252            Unauthorized, self.browser.open, self.manage_container_path)
253        return
254
255    def test_add_search_edit_delete_manage_hostels(self):
256        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
257        self.browser.open(self.container_path)
258        self.browser.getLink("Manage accommodation").click()
259        self.assertEqual(self.browser.headers['Status'], '200 Ok')
260        self.assertEqual(self.browser.url, self.manage_container_path)
261        self.browser.getControl("Add hostel").click()
262        self.assertEqual(self.browser.headers['Status'], '200 Ok')
263        self.assertEqual(self.browser.url, self.add_hostel_path)
264        self.browser.getControl("Create hostel").click()
265        self.assertEqual(self.browser.headers['Status'], '200 Ok')
266        self.assertTrue('Hostel created' in self.browser.contents)
267        self.browser.open(self.container_path + '/addhostel')
268        self.browser.getControl("Create hostel").click()
269        self.assertTrue('The hostel already exists' in self.browser.contents)
270        hall = self.app['hostels']['hall-1']
271        hall.blocks_for_female = ['A','B']
272        self.browser.open(self.container_path + '/hall-1')
273        expected = '...<ul id="form.blocks_for_female" ><li>Block A</li>...'
274        self.assertMatches(expected,self.browser.contents)
275        self.browser.open(self.container_path + '/hall-1/manage')
276        self.browser.getControl(name="form.rooms_per_floor").value = '1'
277        self.browser.getControl("Save").click()
278        self.assertTrue('Form has been saved' in self.browser.contents)
279        # Since the testbrowser does not support Javascrip the
280        # save action cleared the settings above and we have to set them
281        # again.
282        self.assertTrue(len(hall.blocks_for_female) == 0)
283        hall.blocks_for_female = ['A','B']
284        hall.beds_for_fresh = ['A']
285        hall.beds_for_returning = ['B']
286        hall.beds_for_final = ['C']
287        hall.beds_for_all = ['D','E']
288        self.browser.getControl("Update all beds").click()
289        expected = '...0 empty beds removed, 10 beds added, 0 occupied beds modified ()...'
290        self.assertMatches(expected,self.browser.contents)
291        cat = queryUtility(ICatalog, name='beds_catalog')
292        results = cat.searchResults(
293            bed_type=('regular_female_all', 'regular_female_all'))
294        results = [(x.bed_id, x.bed_type) for x in results]
295        self.assertEqual(results,
296            [(u'hall-1_A_101_D', u'regular_female_all'),
297             (u'hall-1_A_101_E', u'regular_female_all'),
298             (u'hall-1_B_101_D', u'regular_female_all'),
299             (u'hall-1_B_101_E', u'regular_female_all')])
300        # Reserve beds.
301        self.browser.getControl("Switch reservation", index=0).click()
302        self.assertTrue('No item selected' in self.browser.contents)
303        ctrl = self.browser.getControl(name='val_id')
304        ctrl.getControl(value='hall-1_A_101_A').selected = True
305        ctrl.getControl(value='hall-1_A_101_B').selected = True
306        ctrl.getControl(value='hall-1_A_101_C').selected = True
307        ctrl.getControl(value='hall-1_A_101_D').selected = True
308        self.browser.getControl("Switch reservation", index=0).click()
309        self.assertTrue('Successfully switched beds: hall-1_A_101_A (reserved)'
310            in self.browser.contents)
311        self.assertEqual(self.app['hostels']['hall-1'][
312            'hall-1_A_101_D'].bed_type, 'regular_female_reserved')
313        self.assertTrue('A_101_A&nbsp;&nbsp;' in self.browser.contents)
314        # The catalog has been updated.
315        results = cat.searchResults(
316            bed_type=('regular_female_all', 'regular_female_all'))
317        results = [(x.bed_id, x.bed_type) for x in results]
318        self.assertEqual(results,
319            [(u'hall-1_A_101_E', u'regular_female_all'),
320             (u'hall-1_B_101_D', u'regular_female_all'),
321             (u'hall-1_B_101_E', u'regular_female_all')])
322        results = cat.searchResults(
323            bed_type=('regular_female_reserved', 'regular_female_reserved'))
324        results = [(x.bed_id, x.bed_type) for x in results]
325        self.assertEqual(results,
326            [(u'hall-1_A_101_A', u'regular_female_reserved'),
327             (u'hall-1_A_101_B', u'regular_female_reserved'),
328             (u'hall-1_A_101_C', u'regular_female_reserved'),
329             (u'hall-1_A_101_D', u'regular_female_reserved')])
330        # Change hostel configuration with one bed booked.
331        hall['hall-1_A_101_E'].owner = u'anyid'
332        notify(grok.ObjectModifiedEvent(hall['hall-1_A_101_E']))
333        hall.beds_for_fresh = ['A', 'E']
334        hall.beds_for_all = ['D']
335        self.browser.getControl("Update all beds").click()
336        expected = '...9 empty beds removed, 9 beds added, 1 occupied beds modified...'
337        self.assertMatches(expected,self.browser.contents)
338        # Updating beds (including booked beds!) does update catalog.
339        results = cat.searchResults(
340            bed_type=('regular_female_all', 'regular_female_all'))
341        results = [(x.bed_id, x.bed_type) for x in results]
342        self.assertEqual(results,
343            [(u'hall-1_B_101_D', u'regular_female_all'),])
344        # Unreserve beds.
345        ctrl = self.browser.getControl(name='val_id')
346        ctrl.getControl(value='hall-1_A_101_A').selected = True
347        ctrl.getControl(value='hall-1_A_101_B').selected = True
348        ctrl.getControl(value='hall-1_A_101_C').selected = True
349        ctrl.getControl(value='hall-1_A_101_D').selected = True
350        self.browser.getControl("Switch reservation", index=0).click()
351        assert self.app['hostels']['hall-1'][
352            'hall-1_A_101_D'].bed_type == 'regular_female_all'
353        self.assertFalse(expected in self.browser.contents)
354        # Release bed which has previously been booked.
355        bedticket = BedTicket()
356        bedticket.booking_session = 2004
357        bedticket.bed_coordinates = u'anything'
358        self.student['accommodation'].addBedTicket(bedticket)
359        self.app['hostels']['hall-1']['hall-1_A_101_D'].owner = self.student_id
360        notify(grok.ObjectModifiedEvent(self.app['hostels']['hall-1']['hall-1_A_101_D']))
361        self.browser.open(self.container_path + '/hall-1/manage')
362        ctrl = self.browser.getControl(name='val_id')
363        self.browser.getControl("Release selected beds", index=0).click()
364        self.assertMatches("...No item selected...", self.browser.contents)
365        ctrl = self.browser.getControl(name='val_id')
366        ctrl.getControl(value='hall-1_A_101_D').selected = True
367        self.browser.getControl("Release selected beds", index=0).click()
368        self.assertMatches(
369          '...Successfully released beds: hall-1_A_101_D (%s)...' % self.student_id,
370          self.browser.contents)
371        self.assertMatches(bedticket.bed_coordinates,
372          u' -- booking cancelled on <YYYY-MM-DD hh:mm:ss> UTC --')
373        # The catalog has been updated.
374        results = cat.searchResults(owner=(self.student_id, self.student_id))
375        assert len(results) == 0
376        # If we release a free bed, nothing will happen.
377        ctrl = self.browser.getControl(name='val_id')
378        ctrl.getControl(value='hall-1_A_101_D').selected = True
379        self.browser.getControl("Release selected beds", index=0).click()
380        self.assertMatches(
381          '...No allocated bed selected...', self.browser.contents)
382        # Managers can manually allocate eligible students after cancellation.
383        self.browser.open(self.container_path + '/hall-1/hall-1_A_101_A')
384        # 'not occupied' is not accepted.
385        self.browser.getControl("Save").click()
386        self.assertMatches(
387            "...No valid student id...",
388            self.browser.contents)
389        # Invalid student ids are not accepted.
390        self.browser.getControl(name="form.owner").value = 'nonsense'
391        self.browser.getControl("Save").click()
392        self.assertMatches(
393            "...Either student does not exist or student "
394            "is not in accommodation session...",
395            self.browser.contents)
396        self.browser.getControl(name="form.owner").value = self.student_id
397        self.browser.getControl("Save").click()
398        self.assertMatches("...Form has been saved...", self.browser.contents)
399        # Students can only be allocated once.
400        self.browser.open(self.container_path + '/hall-1/hall-1_A_101_B')
401        self.browser.getControl(name="form.owner").value = self.student_id
402        self.browser.getControl("Save").click()
403        self.assertMatches(
404            "...This student resides in bed hall-1_A_101_A...",
405            self.browser.contents)
406        # If we open the same form again, we will be redirected to hostel
407        # manage page. Beds must be released first before they can be
408        # allocated to other students.
409        self.browser.open(self.container_path + '/hall-1/hall-1_A_101_A')
410        self.assertEqual(self.browser.url,
411            self.container_path + '/hall-1/@@manage#tab2')
412        # Updating the beds again will not affect the allocation and also
413        # the bed numbering remains the same.
414        old_number = self.app['hostels']['hall-1']['hall-1_A_101_A'].bed_number
415        old_owner = self.app['hostels']['hall-1']['hall-1_A_101_A'].owner
416        self.browser.getControl("Update all beds").click()
417        # 8 beds have been removed and re-added, 2 beds remains untouched
418        # because they are occupied.
419        expected = '...8 empty beds removed, 8 beds added, 0 occupied beds modified...'
420        self.assertMatches(expected,self.browser.contents)
421        new_number = self.app['hostels']['hall-1']['hall-1_A_101_A'].bed_number
422        new_owner = self.app['hostels']['hall-1']['hall-1_A_101_A'].owner
423        self.assertEqual(new_number, old_number)
424        self.assertEqual(new_owner, old_owner)
425        # If we change the bed type of an allocated bed, the modification will
426        # be indicated.
427        hall.blocks_for_female = ['B']
428        hall.blocks_for_male = ['A']
429        self.browser.getControl("Update all beds").click()
430        expected = '...8 empty beds removed, 8 beds added, ' + \
431            '2 occupied beds modified (hall-1_A_101_A, hall-1_A_101_E, )...'
432        self.assertMatches(expected,self.browser.contents)
433        new_number = self.app['hostels']['hall-1']['hall-1_A_101_A'].bed_number
434        # Also the number of the bed has changed.
435        self.assertFalse(new_number == old_number)
436        # The number of occupied beds are displayed on container page.
437        self.browser.open(self.container_path)
438        self.assertTrue('2 of 10' in self.browser.contents)
439        # Remove entire hostel.
440        self.browser.open(self.manage_container_path)
441        ctrl = self.browser.getControl(name='val_id')
442        value = ctrl.options[0]
443        ctrl.getControl(value=value).selected = True
444        self.browser.getControl("Remove selected", index=0).click()
445        self.assertTrue('Successfully removed' in self.browser.contents)
446        # Catalog is empty.
447        results = cat.searchResults(
448            bed_type=('regular_female_all', 'regular_female_all'))
449        results = [x for x in results]
450        assert len(results) == 0
451        # Actions are logged.
452        logcontent = open(self.logfile).read()
453        self.assertTrue(
454            'hall-1 - 9 empty beds removed, 9 beds added, 1 occupied '
455            'beds modified (hall-1_A_101_E, )'
456            in logcontent)
457
458    def test_clear_hostels(self):
459        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
460        self.browser.open(self.container_path)
461        self.browser.getLink("Manage accommodation").click()
462        self.browser.getControl("Add hostel").click()
463        self.browser.getControl("Create hostel").click()
464        hall = self.app['hostels']['hall-1']
465        hall.blocks_for_female = ['A','B']
466        hall.rooms_per_floor = 1
467        hall.beds_for_fresh = ['A']
468        hall.beds_for_returning = ['B']
469        hall.beds_for_final = ['C']
470        hall.beds_for_all = ['D','E']
471        self.browser.open(self.container_path + '/hall-1/manage')
472        self.browser.getControl("Update all beds").click()
473        cat = queryUtility(ICatalog, name='beds_catalog')
474        results = cat.searchResults(bed_type=(None, None))
475        self.assertEqual(len(results), 11)
476        self.browser.getControl("Clear hostel").click()
477        self.assertEqual(len(self.app['hostels']['hall-1']), 0)
478        # Only the bed in hall-x remains in the catalog.
479        results = cat.searchResults(bed_type=(None, None))
480        self.assertEqual(len(results), 1)
481        # We can clear all hostels at the same time.
482        self.browser.open(self.manage_container_path)
483        self.browser.getControl("Clear all hostels").click()
484        results = cat.searchResults(bed_type=(None, None))
485        self.assertEqual(len(results), 0)
486        # Both actions have been logged.
487        logcontent = open(self.logfile).read()
488        self.assertTrue('INFO - zope.mgr - hostels.browser.HostelManageFormPage'
489                        ' - hall-1 - cleared' in logcontent)
490        self.assertTrue('zope.mgr - hostels.browser.HostelsContainerManagePage'
491                        ' - hostels - all hostels cleared' in logcontent)
492
493class ExportTests(HostelsFullSetup):
494
495    layer = FunctionalLayer
496
497    def setUp(self):
498        super(ExportTests, self).setUp()
499        self.workdir = tempfile.mkdtemp()
500        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
501        return
502
503    def test_export_hostels(self):
504        exporter = HostelExporter()
505        exporter.export_all(self.app, self.outfile)
506        result = open(self.outfile, 'rb').read()
507        self.assertEqual(
508            result,
509            'beds_for_all,beds_for_final,beds_for_fresh,beds_for_pre,'
510            'beds_for_returning,beds_reserved,blocks_for_female,'
511            'blocks_for_male,floors_per_block,hostel_id,hostel_name,maint_fee,'
512            'rooms_per_floor,sort_id,special_handling\r\n,,,,,[],,,1,'
513            'hall-x,Hall 1,0.0,2,10,regular\r\n'
514            )
515        return
516
517    def test_export_beds(self):
518        exporter = BedExporter()
519        exporter.export_all(self.app, self.outfile)
520        result = open(self.outfile, 'rb').read()
521        self.assertEqual(
522            result,
523            'bed_id,bed_number,bed_type,owner,hall,block,room,bed,'
524            'special_handling,sex,bt\r\nhall_block_room_bed,1,a_b_c,,'
525            'hall,block,room,bed,a,b,c\r\n'
526            )
527        return
528
529    def tearDown(self):
530        super(ExportTests, self).tearDown()
531        clearSite()
532        shutil.rmtree(os.path.dirname(self.outfile))
533
534class HostelProcessorTest(HostelsFullSetup):
535
536    layer = FunctionalLayer
537
538    def test_import(self):
539        self.processor = HostelProcessor()
540        self.workdir = tempfile.mkdtemp()
541        self.csv_file = os.path.join(self.workdir, 'sample_hostel_data.csv')
542        open(self.csv_file, 'wb').write(HOSTEL_SAMPLE_DATA)
543        num, num_warns, fin_file, fail_file = self.processor.doImport(
544            self.csv_file, HOSTEL_HEADER_FIELDS)
545        self.assertEqual(num_warns,0)
546        self.assertEqual(len(self.app['hostels'].keys()), 11) # including hall-x
547        self.assertEqual(self.app['hostels'][
548            'block-a-upper-hostel'].hostel_id,'block-a-upper-hostel')
549        self.assertEqual(self.app['hostels'][
550            'block-a-upper-hostel'].beds_for_final, ['A', 'B'])
551        logcontent = open(self.logfile).read()
552        self.assertTrue(
553            "Hostel Processor - sample_hostel_data - block-a-upper-hostel - "
554            "updated: "
555            "beds_for_pre=['G'], floors_per_block=1, "
556            "beds_for_final=['A', 'B'], rooms_per_floor=32, "
557            "hostel_id=block-a-upper-hostel, "
558            "sort_id=20, beds_for_returning=['C', 'D'], "
559            "hostel_name=Block A Upper Hostel, beds_for_fresh=['E', 'F'], "
560            "blocks_for_female=['A']"
561            in logcontent)
562        shutil.rmtree(os.path.dirname(fin_file))
563        shutil.rmtree(self.workdir)
564        return
565
566    def test_import_update(self):
567        self.processor = HostelProcessor()
568        self.workdir = tempfile.mkdtemp()
569        self.csv_file = os.path.join(self.workdir, 'sample_hostel_data.csv')
570        open(self.csv_file, 'wb').write(HOSTEL_SAMPLE_DATA)
571        self.csv_file = os.path.join(self.workdir, 'sample_hostel_data.csv')
572        open(self.csv_file, 'wb').write(HOSTEL_SAMPLE_DATA)
573        num, num_warns, fin_file, fail_file = self.processor.doImport(
574            self.csv_file, HOSTEL_HEADER_FIELDS)
575        # We import the same file in update mode
576        num, num_warns, fin_file, fail_file = self.processor.doImport(
577            self.csv_file, HOSTEL_HEADER_FIELDS, 'update')
578        self.assertEqual(num_warns,0)
579        logcontent = open(self.logfile).read()
580        self.assertTrue(
581            "Hostel Processor - sample_hostel_data - block-a-upper-hostel - "
582            "updated: "
583            "beds_for_pre=['G'], floors_per_block=1, "
584            "beds_for_final=['A', 'B'], rooms_per_floor=32, "
585            "hostel_id=block-a-upper-hostel, "
586            "sort_id=20, beds_for_returning=['C', 'D'], "
587            "hostel_name=Block A Upper Hostel, beds_for_fresh=['E', 'F'], "
588            "blocks_for_female=['A']"
589            in logcontent)
590        shutil.rmtree(os.path.dirname(fin_file))
591        shutil.rmtree(self.workdir)
592        return
Note: See TracBrowser for help on using the repository browser.