1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
18 from datetime
import timedelta
, datetime
, date
, time
19 from operator
import itemgetter
23 from indico
.core
.errors
import IndicoError
24 from indico
.modules
.rb
import settings
as rb_settings
25 from indico
.modules
.rb
.models
.blocked_rooms
import BlockedRoom
26 from indico
.modules
.rb
.models
.photos
import Photo
27 from indico
.modules
.rb
.models
.reservations
import RepeatFrequency
28 from indico
.modules
.rb
.models
.room_bookable_hours
import BookableHours
29 from indico
.modules
.rb
.models
.rooms
import Room
30 from indico
.testing
.util
import bool_matrix
31 from indico
.util
.date_time
import get_day_start
, get_day_end
32 from indico
.util
.struct
.iterables
import powerset
35 pytest_plugins
= 'indico.modules.rb.testing.fixtures'
39 def assert_is_in_digest_window(room
, expected
, expected_with_exclude
):
40 assert room
.is_in_digest_window() == expected
41 assert room
.is_in_digest_window(exclude_first_day
=True) == expected_with_exclude
42 assert Room
.find_first(Room
.is_in_digest_window()) == (room
if expected
else None)
43 assert Room
.find_first(Room
.is_in_digest_window(exclude_first_day
=True)) == (room
if expected_with_exclude
47 digest_window_cases
= (
48 # W: window T: today B: both
50 ('2014-10-01', 99, True, True), # |T------------------------------|
51 ('2014-10-01', 99, True, True), # |-T-----------------------------|
52 ('2014-10-16', 31, True, True), # |W--------------T---------------|
53 ('2014-10-16', 17, True, True), # |--------------WT---------------|
54 ('2014-10-16', 16, True, False), # |---------------B---------------|
55 ('2014-10-16', 15, False, False), # |---------------TW--------------|
56 ('2014-10-30', 1, False, False), # |-----------------------------TW|
57 ('2014-10-31', 1, True, False), # |------------------------------B|
58 ('2014-11-01', 1, True, True), # |------------------------------W|T
59 ('2014-11-02', 1, False, False), # |------------------------------W|-T
63 @pytest.mark
.parametrize('need_confirmation', (True, False))
64 def test_is_auto_confirm(create_room
, need_confirmation
):
65 room
= create_room(reservations_need_confirmation
=need_confirmation
)
66 assert room
.is_auto_confirm
!= need_confirmation
67 assert Room
.find_first(is_auto_confirm
=need_confirmation
) is None
68 assert Room
.find_first(is_auto_confirm
=not need_confirmation
) == room
71 def test_urls_transient_object():
73 assert room
.booking_url
is None
74 assert room
.details_url
is None
75 assert room
.large_photo_url
is None
76 assert room
.small_photo_url
is None
79 def test_urls(dummy_room
):
80 assert dummy_room
.booking_url
is not None
81 assert dummy_room
.details_url
is not None
82 assert dummy_room
.large_photo_url
is not None
83 assert dummy_room
.small_photo_url
is not None
86 def test_has_photo(db
, dummy_room
):
87 assert not dummy_room
.has_photo
88 dummy_room
.photo
= Photo()
90 assert dummy_room
.has_photo
93 @pytest.mark
.parametrize(('building', 'floor', 'number', 'name', 'expected_name'), (
94 (u
'1', u
'2', u
'3', u
'', u
'1-2-3'),
95 (u
'1', u
'2', u
'X', u
'', u
'1-2-X'),
96 (u
'1', u
'X', u
'3', u
'', u
'1-X-3'),
97 (u
'X', u
'2', u
'3', u
'', u
'X-2-3'),
98 (u
'1', u
'2', u
'3', u
'Test', u
'1-2-3 - Test'),
99 (u
'1', u
'2', u
'3', u
'm\xf6p', u
'1-2-3 - m\xf6p')
101 def test_full_name(create_room
, building
, floor
, number
, name
, expected_name
):
102 room
= create_room(building
=building
, floor
=floor
, number
=number
, name
=name
)
103 assert room
.full_name
== expected_name
106 @pytest.mark
.parametrize(('name', 'expected'), (
111 def test_has_special_name(create_room
, name
, expected
):
112 room
= create_room(name
=name
)
113 assert room
.has_special_name
== expected
116 @pytest.mark
.parametrize(('value', 'expected'), (
120 def test_has_booking_groups(create_room_attribute
, dummy_room
, value
, expected
):
121 create_room_attribute(u
'allowed-booking-group')
122 assert not dummy_room
.has_booking_groups
123 dummy_room
.set_attribute_value(u
'allowed-booking-group', value
)
124 assert dummy_room
.has_booking_groups
== expected
127 def test_has_projector(create_equipment_type
, dummy_room
, db
):
128 assert not dummy_room
.has_projector
129 dummy_room
.available_equipment
.append(create_equipment_type(u
'Computer Projector'))
131 assert dummy_room
.has_projector
134 def test_has_webcast_recording(create_equipment_type
, dummy_room
, db
):
135 assert not dummy_room
.has_webcast_recording
136 dummy_room
.available_equipment
.append(create_equipment_type(u
'Webcast/Recording'))
138 assert dummy_room
.has_webcast_recording
141 def test_has_vc(create_equipment_type
, dummy_room
, db
):
142 assert not dummy_room
.has_vc
143 dummy_room
.available_equipment
.append(create_equipment_type(u
'Video conference'))
145 assert dummy_room
.has_vc
148 @pytest.mark
.parametrize(('reservable', 'booking_group', 'expected'), (
150 (True, u
'foo', False),
152 (False, u
'foo', False)
154 def test_is_public(create_room_attribute
, dummy_room
, reservable
, booking_group
, expected
):
155 create_room_attribute(u
'allowed-booking-group')
156 dummy_room
.set_attribute_value(u
'allowed-booking-group', booking_group
)
157 dummy_room
.is_reservable
= reservable
158 assert dummy_room
.is_public
== expected
161 @pytest.mark
.parametrize(('is_reservable', 'reservations_need_confirmation', 'booking_group', 'expected_kind'), (
162 (False, False, u
'foo', u
'privateRoom'),
163 (False, True, u
'foo', u
'privateRoom'),
164 (True, False, u
'foo', u
'privateRoom'),
165 (True, True, u
'foo', u
'privateRoom'),
166 (False, False, u
'', u
'privateRoom'),
167 (False, True, u
'', u
'privateRoom'),
168 (True, False, u
'', u
'basicRoom'),
169 (True, True, u
'', u
'moderatedRoom')
171 def test_kind(create_room
, create_room_attribute
,
172 is_reservable
, reservations_need_confirmation
, booking_group
, expected_kind
):
173 room
= create_room(is_reservable
=is_reservable
, reservations_need_confirmation
=reservations_need_confirmation
)
174 create_room_attribute(u
'allowed-booking-group')
175 room
.set_attribute_value(u
'allowed-booking-group', booking_group
)
176 assert room
.kind
== expected_kind
179 def test_location_name(dummy_room
, dummy_location
):
180 assert dummy_room
.location_name
== dummy_location
.name
183 @pytest.mark
.parametrize(('capacity', 'is_reservable', 'reservations_need_confirmation', 'has_vc', 'expected'), (
184 (1, False, True, False, u
'1 person, private, needs confirmation'),
185 (2, False, True, False, u
'2 people, private, needs confirmation'),
186 (2, True, True, False, u
'2 people, public, needs confirmation'),
187 (2, False, False, False, u
'2 people, private, auto-confirmation'),
188 (2, False, True, True, u
'2 people, private, needs confirmation, videoconference')
190 def test_marker_description(db
, create_room
, create_equipment_type
,
191 capacity
, is_reservable
, reservations_need_confirmation
, has_vc
, expected
):
192 room
= create_room(capacity
=capacity
, is_reservable
=is_reservable
,
193 reservations_need_confirmation
=reservations_need_confirmation
)
195 room
.available_equipment
.append(create_equipment_type(u
'Video conference'))
197 assert room
.marker_description
== expected
200 def test_owner(dummy_room
, dummy_user
):
201 assert dummy_room
.owner
== dummy_user
204 def test_owner_after_change(dummy_room
, create_user
):
205 other_user
= create_user(123)
206 dummy_room
.owner
= other_user
207 assert dummy_room
.owner
== other_user
210 @pytest.mark
.parametrize(('value', 'emails'), (
212 (u
'example@example.com', {u
'example@example.com'}),
213 (u
' example@example.com ,m\xf6p@example.cm\xf6pm ', {u
'example@example.com', u
'm\xf6p@example.cm\xf6pm'}),
215 def test_notification_emails(create_room_attribute
, dummy_room
, value
, emails
):
216 create_room_attribute(u
'notification-email')
217 dummy_room
.set_attribute_value(u
'notification-email', value
)
218 assert dummy_room
.notification_emails
== emails
221 @pytest.mark
.parametrize(('name', 'expected'), (
224 (u
'xxx', False), # existent
225 (u
'yyy', False), # not existent
227 def test_has_equipment(create_equipment_type
, dummy_room
, name
, expected
):
228 dummy_room
.available_equipment
.append(create_equipment_type(u
'foo'))
229 dummy_room
.available_equipment
.append(create_equipment_type(u
'bar'))
230 create_equipment_type(u
'xxx')
231 assert dummy_room
.has_equipment(name
) == expected
234 def test_find_available_vc_equipment(db
, dummy_room
, create_equipment_type
):
235 foo
= create_equipment_type(u
'foo')
236 vc
= create_equipment_type(u
'Video conference')
237 vc_items
= [create_equipment_type(u
'vc1'), create_equipment_type(u
'vc2')]
238 vc
.children
+= vc_items
239 dummy_room
.available_equipment
.extend(vc_items
+ [vc
, foo
])
241 assert set(dummy_room
.find_available_vc_equipment()) == set(vc_items
)
244 def test_get_attribute_by_name(create_room_attribute
, dummy_room
):
245 attr
= create_room_attribute(u
'foo')
246 assert dummy_room
.get_attribute_by_name(u
'foo') is None
247 dummy_room
.set_attribute_value(u
'foo', u
'bar')
248 assert dummy_room
.get_attribute_by_name(u
'foo').attribute
== attr
251 def test_has_attribute(create_room_attribute
, dummy_room
):
252 create_room_attribute(u
'foo')
253 assert not dummy_room
.has_attribute(u
'foo')
254 dummy_room
.set_attribute_value(u
'foo', u
'bar')
255 assert dummy_room
.has_attribute(u
'foo')
258 @pytest.mark
.parametrize(('value', 'expected'), (
266 (['a', 'b'], ['a', 'b']),
268 def test_get_attribute_value(create_room_attribute
, dummy_room
, value
, expected
):
269 assert dummy_room
.get_attribute_value(u
'foo', _notset
) is _notset
270 create_room_attribute(u
'foo')
271 assert dummy_room
.get_attribute_value(u
'foo', _notset
) is _notset
272 dummy_room
.set_attribute_value(u
'foo', value
)
273 assert dummy_room
.get_attribute_value(u
'foo', _notset
) == expected
276 def test_set_attribute_value(create_room_attribute
, dummy_room
):
277 # setting an attribute that doesn't exist fails
278 with pytest
.raises(ValueError):
279 dummy_room
.set_attribute_value(u
'foo', u
'something')
280 create_room_attribute(u
'foo')
281 # the value can be cleared even if it is not set
282 dummy_room
.set_attribute_value(u
'foo', None)
283 assert dummy_room
.get_attribute_value(u
'foo', _notset
) is _notset
284 # set it to some value
285 dummy_room
.set_attribute_value(u
'foo', u
'test')
286 assert dummy_room
.get_attribute_value(u
'foo') == u
'test'
287 # set to some other value while we have an existing association entry
288 dummy_room
.set_attribute_value(u
'foo', u
'something')
289 assert dummy_room
.get_attribute_value(u
'foo') == u
'something'
291 dummy_room
.set_attribute_value(u
'foo', None)
292 assert dummy_room
.get_attribute_value(u
'foo', _notset
) is _notset
295 def test_getLocator(dummy_location
, dummy_room
):
296 assert dummy_room
.getLocator() == {'roomLocation': dummy_location
.name
, 'roomID': dummy_room
.id}
299 @pytest.mark
.parametrize(('building', 'floor', 'number', 'name', 'expected_name'), (
300 (u
'1', u
'2', u
'3', u
'', u
'1-2-3'),
301 (u
'1', u
'2', u
'X', u
'', u
'1-2-X'),
302 (u
'1', u
'X', u
'3', u
'', u
'1-X-3'),
303 (u
'X', u
'2', u
'3', u
'', u
'X-2-3'),
304 (u
'1', u
'2', u
'3', u
'Test', u
'Test')
306 def test_update_name(create_room
, building
, floor
, number
, name
, expected_name
):
308 room
.building
= building
312 assert room
.name
== name
314 assert room
.name
== expected_name
317 def test_find_all(create_location
, create_room
):
318 # Here we just test if we get the rooms in natural sort order
319 loc1
= create_location('Z')
320 loc2
= create_location('A')
322 (2, dict(location
=loc1
, building
=u
'1', floor
=u
'2', number
=u
'3', name
=u
'')),
323 (3, dict(location
=loc1
, building
=u
'2', floor
=u
'2', number
=u
'3', name
=u
'')),
324 (5, dict(location
=loc1
, building
=u
'100', floor
=u
'2', number
=u
'3', name
=u
'')),
325 (4, dict(location
=loc1
, building
=u
'10', floor
=u
'2', number
=u
'3', name
=u
'')),
326 (1, dict(location
=loc2
, building
=u
'999', floor
=u
'2', number
=u
'3', name
=u
''))
328 rooms
= [(pos
, create_room(**params
)) for pos
, params
in data
]
329 sorted_rooms
= map(itemgetter(1), sorted(rooms
, key
=itemgetter(0)))
330 assert sorted_rooms
== Room
.find_all()
333 def test_find_with_attribute(dummy_room
, create_room
, create_room_attribute
):
334 assert Room
.find_all() == [dummy_room
] # one room without the attribute
335 assert not Room
.find_with_attribute(u
'foo')
336 create_room_attribute(u
'foo')
337 assert not Room
.find_with_attribute(u
'foo')
339 for room
in [create_room(), create_room()]:
340 value
= u
'bar-{}'.format(room
.id)
341 room
.set_attribute_value(u
'foo', value
)
342 expected
.add((room
, value
))
343 assert set(Room
.find_with_attribute(u
'foo')) == expected
346 def test_get_with_data_errors():
347 with pytest
.raises(ValueError):
348 Room
.get_with_data(foo
='bar')
351 @pytest.mark
.parametrize(('only_active', 'data'), list(itertools
.product(
353 powerset(('equipment', 'vc_equipment', 'non_vc_equipment'))
355 def test_get_with_data(db
, create_room
, create_equipment_type
, only_active
, data
):
356 eq
= create_equipment_type(u
'eq')
357 vc
= create_equipment_type(u
'Video conference')
358 vc1
= create_equipment_type(u
'vc1')
359 vc2
= create_equipment_type(u
'vc2')
360 vc
.children
.append(vc1
)
361 vc
.children
.append(vc2
)
364 'inactive': {'room': create_room(is_active
=False),
366 'vc_equipment': set(),
367 'non_vc_equipment': set()},
368 'no_eq': {'room': create_room(),
370 'vc_equipment': set(),
371 'non_vc_equipment': set()},
372 'non_vc_eq': {'room': create_room(),
374 'vc_equipment': set(),
375 'non_vc_equipment': {eq}
},
376 'vc_eq': {'room': create_room(),
377 'equipment': {vc
, vc1
, vc2
},
378 'vc_equipment': {vc1
, vc2
},
379 'non_vc_equipment': {vc}
},
380 'all_eq': {'room': create_room(),
381 'equipment': {eq
, vc
, vc1
, vc2
},
382 'vc_equipment': {vc1
, vc2
},
383 'non_vc_equipment': {vc
, eq
}}
385 room_types
= {room_data
['room']: type_
for type_
, room_data
in rooms
.iteritems()}
386 for room
in rooms
.itervalues():
387 room
['room'].available_equipment
= room
['equipment']
389 results
= list(Room
.get_with_data(*data
, only_active
=only_active
))
390 assert len(results
) == len(rooms
) - only_active
392 room
= row
.pop('room')
393 assert row
.viewkeys() == set(data
)
394 room_type
= room_types
[room
]
395 if room_type
== 'inactive':
396 assert not only_active
398 assert set(row
[key
]) == {x
.name
for x
in rooms
[room_type
][key
]}
401 def test_max_capacity(create_room
):
402 assert not Room
.query
.count()
403 assert Room
.max_capacity
== 0
404 create_room(capacity
=0)
405 assert Room
.max_capacity
== 0
406 create_room(capacity
=10)
407 create_room(capacity
=5)
408 assert Room
.max_capacity
== 10
411 @pytest.mark
.parametrize(
412 ('has_booking', 'has_blocking',
413 'has_pre_booking', 'include_pre_bookings',
414 'has_pending_blocking', 'include_pending_blockings',
416 set(bool_matrix('00.0.0', expect
=False) + # nothing confirmed/pending
417 bool_matrix('000.0.', expect
=False) + # nothing pending included
418 bool_matrix('1.....', expect
=True) + # confirmed booking
419 bool_matrix('.1....', expect
=True) + # active blocking
420 bool_matrix('00....', expect
=lambda x
: all(x
[2:4]) or all(x
[4:6]))) # included pending booking/blocking
422 def test_filter_available(dummy_room
, create_reservation
, create_blocking
,
423 has_booking
, has_blocking
,
424 has_pre_booking
, include_pre_bookings
,
425 has_pending_blocking
, include_pending_blockings
, filtered
):
427 create_reservation(start_dt
=datetime
.combine(date
.today(), time(8)),
428 end_dt
=datetime
.combine(date
.today(), time(10)))
430 create_reservation(start_dt
=datetime
.combine(date
.today(), time(10)),
431 end_dt
=datetime
.combine(date
.today(), time(12)),
434 create_blocking(state
=BlockedRoom
.State
.accepted
)
435 if has_pending_blocking
:
436 create_blocking(state
=BlockedRoom
.State
.pending
)
437 availabilty_filter
= Room
.filter_available(get_day_start(date
.today()), get_day_end(date
.today()),
438 (RepeatFrequency
.NEVER
, 0),
439 include_pre_bookings
=include_pre_bookings
,
440 include_pending_blockings
=include_pending_blockings
)
441 assert set(Room
.find_all(availabilty_filter
)) == (set() if filtered
else {dummy_room}
)
444 def test_find_with_filters(db
, dummy_room
, create_room
, dummy_user
, create_equipment_type
, create_room_attribute
,
446 # Simple testcase that ensures we find the room when many filters are used
447 other_room
= create_room()
448 assert set(Room
.find_with_filters({}, dummy_user
)) == {dummy_room
, other_room
}
449 create_room_attribute(u
'attr')
450 eq
= create_equipment_type(u
'eq')
451 dummy_room
.capacity
= 100
452 dummy_room
.is_reservable
= True
453 dummy_room
.available_equipment
.append(eq
)
454 dummy_room
.set_attribute_value(u
'attr', u
'meowmeow')
456 filters
= {'available_equipment': {eq}
,
459 'is_only_my_rooms': True,
462 'repeatability': 'None',
463 'start_dt': dummy_reservation
.start_dt
,
464 'end_dt': dummy_reservation
.end_dt
}
465 assert set(Room
.find_with_filters(filters
, dummy_user
)) == {dummy_room}
468 def test_find_with_filters_equipment(db
, dummy_room
, create_room
, create_equipment_type
):
469 other_room
= create_room()
470 assert set(Room
.find_with_filters({}, None)) == set(Room
.find_all())
471 eq1
= create_equipment_type(u
'eq1')
472 eq2
= create_equipment_type(u
'eq2')
473 assert not Room
.find_with_filters({'available_equipment': {eq1}
}, None)
474 dummy_room
.available_equipment
.append(eq1
)
476 assert set(Room
.find_with_filters({'available_equipment': {eq1}
}, None)) == {dummy_room}
477 assert not Room
.find_with_filters({'available_equipment': {eq1
, eq2
}}, None)
478 dummy_room
.available_equipment
.append(eq2
)
479 other_room
.available_equipment
.append(eq2
)
481 assert set(Room
.find_with_filters({'available_equipment': {eq1}
}, None)) == {dummy_room}
482 assert set(Room
.find_with_filters({'available_equipment': {eq2}
}, None)) == {dummy_room
, other_room
}
483 assert set(Room
.find_with_filters({'available_equipment': {eq1
, eq2
}}, None)) == {dummy_room}
486 @pytest.mark
.parametrize(('capacity', 'other_capacity', 'search_capacity', 'match', 'match_other'), (
487 (100, 79, 100, True, False), # 79 outside 80..120
488 (110, 95, 100, True, True), # 110, 95 inside 80..120
489 (120, 80, 100, True, True), # 120, 80 exactly on the edges
490 (121, 80, 100, False, True), # 121 outside range
491 (121, 50, 100, True, False), # 121 exceeds upper bound = match anyway to avoid getting no results
492 (79, 50, 100, False, False), # 79 outside lower bound => hard limit
493 (None, 999, 999, True, True), # no capacity always matches
495 def test_find_with_filters_capacity(db
, dummy_room
, create_room
,
496 capacity
, other_capacity
, search_capacity
, match
, match_other
):
497 other_room
= create_room()
498 assert set(Room
.find_with_filters({}, None)) == set(Room
.find_all())
499 dummy_room
.capacity
= capacity
500 other_room
.capacity
= other_capacity
504 expected
.add(dummy_room
)
506 expected
.add(other_room
)
507 assert set(Room
.find_with_filters({'capacity': search_capacity
}, None)) == expected
510 @pytest.mark
.parametrize(('is_reservable', 'booking_group', 'match'), (
512 (True, u
'foo', False),
513 (False, None, False),
514 (False, u
'foo', False)
516 def test_find_with_filters_only_public(dummy_room
, create_room_attribute
,
517 is_reservable
, booking_group
, match
):
518 create_room_attribute(u
'allowed-booking-group')
519 dummy_room
.is_reservable
= is_reservable
520 dummy_room
.set_attribute_value(u
'allowed-booking-group', booking_group
)
522 assert set(Room
.find_with_filters({'is_only_public': True}, None)) == {dummy_room}
524 assert not Room
.find_with_filters({'is_only_public': True}, None)
527 @pytest.mark
.parametrize(('owner_id', 'match'), (
531 def test_find_with_filters_only_my_rooms(dummy_room
, create_user
, owner_id
, match
):
532 user
= create_user(owner_id
)
534 assert set(Room
.find_with_filters({'is_only_my_rooms': True}, user
)) == {dummy_room}
536 assert not Room
.find_with_filters({'is_only_my_rooms': True}, user
)
539 @pytest.mark
.parametrize('available', (True, False))
540 def test_find_with_filters_availability(dummy_room
, dummy_reservation
, available
):
542 start_dt
= dummy_reservation
.end_dt
+ timedelta(days
=1)
543 end_dt
= start_dt
+ timedelta(days
=1)
545 start_dt
= dummy_reservation
.start_dt
546 end_dt
= dummy_reservation
.end_dt
547 filters
= {'available': int(available
),
548 'repeatability': 'None',
549 'start_dt': start_dt
,
551 assert set(Room
.find_with_filters(filters
, None)) == {dummy_room}
554 def test_find_with_filters_availability_error():
555 with pytest
.raises(ValueError):
556 filters
= {'available': 123,
557 'repeatability': 'None',
558 'start_dt': datetime
.now(),
559 'end_dt': datetime
.now()}
560 Room
.find_with_filters(filters
, None)
563 @pytest.mark
.parametrize('col', ('name', 'site', 'division', 'building', 'floor', 'number', 'telephone',
564 'key_location', 'comments'))
565 def test_find_with_filters_details_cols(db
, dummy_room
, create_room
, col
):
566 create_room() # some room we won't find!
567 assert set(Room
.find_with_filters({}, None)) == set(Room
.find_all())
568 assert not Room
.find_with_filters({'details': u
'meow'}, None)
569 setattr(dummy_room
, col
, u
'meow')
571 assert set(Room
.find_with_filters({'details': u
'meow'}, None)) == {dummy_room}
574 find_with_filters_details
= (
575 (u
'meow', u
'meow', None),
576 (u
'meow', u
'MEOW', None),
577 (u
'foo"bar', u
'foo"bar', None),
578 (ur
'foo\bar', ur
'foo\bar', None),
579 (u
'test%bla', u
'test%bla', u
'testXbla'),
580 (u
'test_bla', u
'test_bla', u
'testXbla')
584 @pytest.mark
.parametrize(('value', 'search_value', 'other_value'), find_with_filters_details
)
585 def test_find_with_filters_details_values(db
, dummy_room
, create_room
, value
, search_value
, other_value
):
586 other_room
= create_room()
587 assert set(Room
.find_with_filters({}, None)) == set(Room
.find_all())
588 assert not Room
.find_with_filters({'details': search_value
}, None)
589 dummy_room
.comments
= value
590 other_room
.comments
= other_value
592 assert set(Room
.find_with_filters({'details': search_value
}, None)) == {dummy_room}
595 @pytest.mark
.parametrize(('value', 'search_value', 'other_value'), find_with_filters_details
)
596 def test_find_with_filters_details_attrs(dummy_room
, create_room
, create_room_attribute
,
597 value
, search_value
, other_value
):
598 other_room
= create_room()
599 assert set(Room
.find_with_filters({}, None)) == set(Room
.find_all())
600 assert not Room
.find_with_filters({'details': search_value
}, None)
601 create_room_attribute(u
'foo')
602 assert not Room
.find_with_filters({'details': search_value
}, None)
603 dummy_room
.set_attribute_value(u
'foo', value
)
604 other_room
.set_attribute_value(u
'foo', other_value
)
605 assert set(Room
.find_with_filters({'details': search_value
}, None)) == {dummy_room}
608 def test_has_live_reservations(dummy_room
, create_reservation
):
609 assert not dummy_room
.has_live_reservations()
610 create_reservation(start_dt
=datetime
.combine(date
.today() - timedelta(days
=1), time(8)),
611 end_dt
=datetime
.combine(date
.today() - timedelta(days
=1), time(10)))
612 assert not dummy_room
.has_live_reservations()
613 create_reservation(start_dt
=datetime
.combine(date
.today() + timedelta(days
=1), time(8)),
614 end_dt
=datetime
.combine(date
.today() + timedelta(days
=1), time(10)))
615 assert dummy_room
.has_live_reservations()
618 @pytest.mark
.parametrize(
619 ('is_admin', 'ignore_admin', 'is_active', 'is_owned_by', 'is_reservable', 'has_group', 'in_group', 'expected'),
620 set(bool_matrix('10.....', expect
=True) + # admin
621 bool_matrix('..0....', mask
='10.....', expect
=False, ) + # inactive
622 bool_matrix('..11...', expect
=True) + # owned
623 bool_matrix('..100..', mask
='10.....', expect
=False) + # not reservable
624 bool_matrix('..1010.', expect
=True) + # no group
625 bool_matrix('..1011.', mask
='10.....', expect
=lambda x
: x
[6])) # user in group
627 def test_can_be_booked(dummy_room
, create_user
, create_room_attribute
, create_group
,
628 is_admin
, ignore_admin
, is_active
, is_owned_by
, is_reservable
, has_group
, in_group
, expected
):
629 create_room_attribute(u
'allowed-booking-group')
630 user
= create_user(123, rb_admin
=is_admin
, legacy
=False)
631 dummy_room
.is_active
= is_active
632 dummy_room
.is_reservable
= is_reservable
634 user
.local_groups
.add(create_group(123).group
)
636 dummy_room
.owner
= user
.as_avatar
638 dummy_room
.set_attribute_value(u
'allowed-booking-group', u
'123')
639 assert dummy_room
.can_be_booked(user
, ignore_admin
=ignore_admin
) == expected
640 assert dummy_room
.can_be_prebooked(user
, ignore_admin
=ignore_admin
) == expected
643 @pytest.mark
.parametrize(
644 ('is_admin', 'ignore_admin', 'is_active', 'is_owned_by', 'is_reservable', 'has_group', 'in_group', 'expected'),
645 set(bool_matrix('10.....', expect
=True) + # admin
646 bool_matrix('..0....', mask
='10.....', expect
=False, ) + # inactive
647 bool_matrix('..11...', expect
=True) + # owned
648 bool_matrix('..100..', mask
='10.....', expect
=False) + # not reservable
649 bool_matrix('..1010.', expect
=True) + # no group
650 bool_matrix('..1011.', mask
='10.....', expect
=lambda x
: x
[6])) # user in group
652 def test_can_be_prebooked(dummy_room
, create_user
, create_room_attribute
, create_group
,
653 is_admin
, ignore_admin
, is_active
, is_owned_by
, is_reservable
, has_group
, in_group
, expected
):
654 create_room_attribute(u
'allowed-booking-group')
655 user
= create_user(123, rb_admin
=is_admin
)
656 dummy_room
.is_active
= is_active
657 dummy_room
.is_reservable
= is_reservable
658 dummy_room
.reservations_need_confirmation
= True
660 user
.user
.local_groups
.add(create_group(123).group
)
662 dummy_room
.owner
= user
664 dummy_room
.set_attribute_value(u
'allowed-booking-group', u
'123')
665 assert dummy_room
.can_be_prebooked(user
, ignore_admin
=ignore_admin
) == expected
668 @pytest.mark
.parametrize(('has_acl', 'in_acl', 'expected'), (
669 (False, False, True),
671 (True, False, False),
673 def test_can_be_booked_prebooked_no_rb_access(db
, dummy_room
, dummy_user
, create_user
, has_acl
, in_acl
, expected
):
674 user
= create_user(123)
676 acl
= [(u
'Avatar', dummy_user
.id)]
678 acl
.append((u
'Avatar', user
.id))
679 rb_settings
.set('authorized_principals', acl
)
681 assert dummy_room
.can_be_booked(user
) == expected
682 assert dummy_room
.can_be_prebooked(user
) == expected
685 @pytest.mark
.parametrize(('is_owner', 'is_admin', 'expected'), bool_matrix('..', expect
=any
))
686 def test_can_be_overridden(dummy_room
, create_user
, is_owner
, is_admin
, expected
):
687 user
= create_user(123, rb_admin
=is_admin
)
689 dummy_room
.owner
= user
690 assert dummy_room
.can_be_overridden(user
) == expected
693 @pytest.mark
.parametrize(('is_admin', 'expected'), (
697 def test_can_be_modified_deleted(dummy_room
, create_user
, is_admin
, expected
):
698 user
= create_user(123, rb_admin
=is_admin
)
699 assert dummy_room
.can_be_modified(user
) == expected
700 assert dummy_room
.can_be_deleted(user
) == expected
703 def test_can_be_no_user(dummy_room
):
704 assert not dummy_room
.can_be_booked(None)
705 assert not dummy_room
.can_be_prebooked(None)
706 assert not dummy_room
.can_be_overridden(None)
707 assert not dummy_room
.can_be_modified(None)
708 assert not dummy_room
.can_be_deleted(None)
711 @pytest.mark
.parametrize(('is_owner', 'has_group', 'in_group', 'expected'),
712 bool_matrix('...', expect
=lambda x
: x
[0] or all(x
[1:])))
713 def test_ownership_functions(dummy_room
, create_user
, create_room_attribute
, create_group
,
714 is_owner
, has_group
, in_group
, expected
):
715 user
= create_user(123)
716 create_room_attribute(u
'manager-group')
718 dummy_room
.owner
= user
720 dummy_room
.set_attribute_value(u
'manager-group', u
'123')
722 user
.user
.local_groups
.add(create_group(123).group
)
723 assert dummy_room
.is_owned_by(user
) == expected
724 assert Room
.user_owns_rooms(user
) == expected
725 assert set(Room
.get_owned_by(user
)) == ({dummy_room}
if expected
else set())
728 @pytest.mark
.parametrize(('is_admin', 'is_owner', 'max_advance_days', 'days_delta', 'success'), (
729 (True, False, 10, 15, True),
730 (False, True, 10, 15, True),
731 (False, False, None, 15, True),
732 (False, False, 0, 15, True),
733 (False, False, 10, -5, True),
734 (False, False, 10, 10, False),
735 (False, False, 10, 15, False)
737 def test_check_advance_days(create_user
, dummy_room
, is_admin
, is_owner
, max_advance_days
, days_delta
, success
):
738 user
= create_user(123, rb_admin
=is_admin
)
739 dummy_room
.max_advance_days
= max_advance_days
740 end_date
= date
.today() + timedelta(days
=days_delta
)
742 dummy_room
.owner
= user
744 assert dummy_room
.check_advance_days(end_date
, user
, quiet
=True)
745 assert dummy_room
.check_advance_days(end_date
, user
)
747 assert not dummy_room
.check_advance_days(end_date
, user
, quiet
=True)
748 with pytest
.raises(IndicoError
):
749 dummy_room
.check_advance_days(end_date
, user
)
752 def test_check_advance_days_no_user(dummy_room
):
753 dummy_room
.max_advance_days
= 10
754 end_date
= date
.today() + timedelta(days
=15)
755 assert not dummy_room
.check_advance_days(end_date
, quiet
=True)
758 @pytest.mark
.parametrize(('is_admin', 'is_owner', 'fits', 'success'), bool_matrix('...', expect
=any
))
759 def test_check_bookable_hours(db
, dummy_room
, create_user
, is_admin
, is_owner
, fits
, success
):
760 user
= create_user(123, rb_admin
=is_admin
)
762 dummy_room
.owner
= user
763 dummy_room
.bookable_hours
= [BookableHours(start_time
=time(12), end_time
=time(14))]
765 booking_hours
= (time(12), time(13)) if fits
else (time(8), time(9))
767 assert dummy_room
.check_bookable_hours(booking_hours
[0], booking_hours
[1], user
, quiet
=True)
768 assert dummy_room
.check_bookable_hours(booking_hours
[0], booking_hours
[1], user
)
770 assert not dummy_room
.check_bookable_hours(booking_hours
[0], booking_hours
[1], user
, quiet
=True)
771 with pytest
.raises(IndicoError
):
772 dummy_room
.check_bookable_hours(booking_hours
[0], booking_hours
[1], user
)
775 def test_check_bookable_hours_hours(dummy_room
):
776 assert dummy_room
.check_bookable_hours(time(8), time(9), quiet
=True)
779 def test_check_bookable_hours_no_user(db
, dummy_room
):
780 dummy_room
.bookable_hours
= [BookableHours(start_time
=time(12), end_time
=time(14))]
782 assert not dummy_room
.check_bookable_hours(time(8), time(9), quiet
=True)
785 @pytest.mark
.parametrize(('current_date', 'notification_window', 'expected', 'expected_with_exclude'),
787 def test_is_in_digest_window(db
, freeze_time
, dummy_room
,
788 current_date
, notification_window
, expected
, expected_with_exclude
):
789 freeze_time(current_date
)
790 dummy_room
.notification_before_days
= notification_window
792 assert_is_in_digest_window(dummy_room
, expected
, expected_with_exclude
)
795 @pytest.mark
.parametrize(('current_date', 'notification_window', 'expected', 'expected_with_exclude'),
797 def test_is_in_digest_window_from_settings(db
, freeze_time
, dummy_room
,
798 current_date
, notification_window
, expected
, expected_with_exclude
):
799 freeze_time(current_date
)
800 dummy_room
.notification_window
= None
801 rb_settings
.set('notification_before_days', notification_window
)
803 assert_is_in_digest_window(dummy_room
, expected
, expected_with_exclude
)
806 @pytest.mark
.parametrize(('current_date', 'expected', 'expected_with_exclude'), (
807 # W: window T: today B: both
809 ('2014-10-30', False, False), # |-----------------------------TW|
810 ('2014-10-31', True, False), # |------------------------------B|
811 ('2014-11-01', True, True), # |------------------------------W|T
812 ('2014-11-02', False, False), # |------------------------------W|-T
814 def test_is_in_digest_window_from_settings_empty(db
, freeze_time
, dummy_room
,
815 current_date
, expected
, expected_with_exclude
):
816 freeze_time(current_date
)
817 dummy_room
.notification_before_days
= None
819 assert_is_in_digest_window(dummy_room
, expected
, expected_with_exclude
)