# -*- coding: utf-8 -*- import datetime from unittest import TestCase from ..config import FieldInitial class FieldInitialTestCase(TestCase): def test_single_argument(self): value = 'a value' fi = FieldInitial(value) session = {'mode': 'a mode'} output = fi.get_value(session) self.assertEqual(output, value) def test_single_argument_empty_session(self): value = 'a value' fi = FieldInitial(value) session = {} output = fi.get_value(session) self.assertEqual(output, value) def test_non_string_value(self): values = (42, False, None) for value in values: fi = FieldInitial(value) session = {} output = fi.get_value(session) self.assertEqual(output, value) def test_single_simple_constraint_session_match(self): args = ( 'sport==heli skiing', 'not allowed', ) fi = FieldInitial(*args) session = {'sport': 'heli skiing'} output = fi.get_value(session) self.assertEqual(output, 'not allowed') def test_single_simple_constraint_session_not_match(self): args = ( 'sport==heli skiing', 'not allowed', ) fi = FieldInitial(*args) session = {'sport': 'Heli Skiing'} output = fi.get_value(session) self.assertEqual(output, None) session = {'sport': 'heli'} output = fi.get_value(session) self.assertEqual(output, None) session = {'mode': 'heli skiing', 'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, None) def test_single_simple_constraint_empty_session(self): args = ( 'sport==heli skiing', 'not allowed', ) fi = FieldInitial(*args) session = {} output = fi.get_value(session) self.assertEqual(output, None) def test_empty_value_in_constraint(self): args = ( 'sport==', 'lazy', ) fi = FieldInitial(*args) session = {'sport': ''} output = fi.get_value(session) self.assertEqual(output, 'lazy') session = {'sport': 'any'} output = fi.get_value(session) self.assertEqual(output, None) def test_invalid_constraints(self): invalid_constraints = ( 'sport', # Not in form 'sport ==hiking' # Blanks before operator 'sport== hiking' # Blanks after operator 'sport!=hiking', # Invalid operator '==hiking', # Missing key ) for constraint in invalid_constraints: fi = FieldInitial(constraint, 'ignored', 'mode==joint', 'recognized') with self.assertLogs('dav_events.config', 'ERROR') as cm: output = fi.get_value({'mode': 'joint'}) self.assertEqual(output, 'recognized') self.assertStartsWith(cm.output[0], 'ERROR:dav_events.config:FieldInitial: Invalid constraint: ') def test_valid_constraint_keys(self): valid_keys = ('mode', 'sport', 'level', 'overnight', 'country', 'terrain', 'transport') for key in valid_keys: fi = FieldInitial('{}==True'.format(key), 'matched') if key == 'overnight': session = {'last_day': 'True'} else: session = {key: 'True'} with self.assertNoLogs('dav_events.config'): output = fi.get_value(session) self.assertEqual(output, 'matched', key) def test_ignore_invalid_constraint_keys(self): invalid_keys = ('ski_lift', 'last_day', 'location') for key in invalid_keys: fi = FieldInitial('{}==True'.format(key), 'ignored', 'mode==joint', 'matched') session = {key: 'True', 'mode': 'joint'} with self.assertLogs('dav_events.config', 'ERROR') as cm: output = fi.get_value(session) self.assertEqual(output, 'matched') self.assertStartsWith(cm.output[0], 'ERROR:dav_events.config:FieldInitial: Invalid field: ') def test_multiple_simple_constraints(self): args = ( 'mode==guided', 'guide', 'sport==biking', 'bicycle', ) fi = FieldInitial(*args) session = {} output = fi.get_value(session) self.assertEqual(output, None) session = {'mode': 'joint'} output = fi.get_value(session) self.assertEqual(output, None) session = {'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, 'bicycle') session = {'mode': 'joint', 'sport': 'hiking'} output = fi.get_value(session) self.assertEqual(output, None) session = {'mode': 'joint', 'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, 'bicycle') session = {'mode': 'guided', 'sport': 'hiking'} output = fi.get_value(session) self.assertEqual(output, 'guide') session = {'mode': 'guided', 'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, 'guide') def test_or(self): args = ( 'sport==hiking', 'shoes', 'sport==biking', 'bicycle', ) fi = FieldInitial(*args) session = {'sport': 'hiking'} output = fi.get_value(session) self.assertEqual(output, 'shoes') session = {'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, 'bicycle') session = {'sport': 'swimming'} output = fi.get_value(session) self.assertEqual(output, None) def test_and(self): args = [] for mode in ('0', '1'): for sport in ('0', '1'): for level in ('0', '1'): constraint_arg = 'mode=={},sport=={},level=={}'.format(mode, sport, level) value = 'mode{}sport{}level{}'.format(mode, sport, level) args.append(constraint_arg) args.append(value) fi = FieldInitial(*args) for mode in ('0', '1', ''): for sport in ('0', '1', '*'): for level in ('0', '1', None): session = {'mode': mode, 'sport': sport, 'level': level} if mode in ('0', '1') and sport in ('0', '1') and level in ('0', '1'): expected_value = 'mode{}sport{}level{}'.format(mode, sport, level) else: expected_value = None output = fi.get_value(session) self.assertEqual(output, expected_value) session = {'mode': '0', 'sport': '0'} output = fi.get_value(session) self.assertEqual(output, None) def test_empty_constraint_only(self): fi = FieldInitial( '', 'default_value' ) session = {} output = fi.get_value(session) self.assertEqual(output, 'default_value') session = {'mode': 'guided'} output = fi.get_value(session) self.assertEqual(output, 'default_value') def test_empty_constraint_match_always(self): # XXX: Unwanted behavior fi = FieldInitial( '', 'default_value', 'mode==guided', 'guide', ) session = {} output = fi.get_value(session) self.assertEqual(output, 'default_value') session = {'mode': 'joint'} output = fi.get_value(session) self.assertEqual(output, 'default_value') session = {'mode': 'guided'} output = fi.get_value(session) self.assertEqual(output, 'default_value') def test_empty_constraint_as_default(self): fi = FieldInitial( 'mode==guided', 'guide', '', 'default_value', ) session = {} output = fi.get_value(session) self.assertEqual(output, 'default_value') session = {'mode': 'joint'} output = fi.get_value(session) self.assertEqual(output, 'default_value') session = {'mode': 'guided'} output = fi.get_value(session) self.assertEqual(output, 'guide') def test_missing_return_value(self): # XXX: Unwanted behavior args = ( 'sport==hiking', 'shoes', 'sport==biking', ) fi = FieldInitial(*args) session = {'sport': 'hiking'} output = fi.get_value(session) self.assertEqual(output, 'shoes') session = {'sport': 'biking'} output = fi.get_value(session) self.assertEqual(output, None) def test_overnight_affected_by_last_day(self): fi = FieldInitial( 'overnight==True', 'overnight_value', 'overnight==False', 'not_overnight_value', ) session = {'last_day': True} output = fi.get_value(session) self.assertEqual(output, 'overnight_value') session = {'last_day': 'Yesterday'} output = fi.get_value(session) self.assertEqual(output, 'overnight_value') session = {'last_day': datetime.date(1900, 1, 1)} output = fi.get_value(session) self.assertEqual(output, 'overnight_value') # XXX: Unwanted behavior session = {'last_day': 'False'} output = fi.get_value(session) self.assertEqual(output, 'overnight_value') session = {'last_day': False} output = fi.get_value(session) self.assertEqual(output, 'not_overnight_value') session = {} output = fi.get_value(session) self.assertEqual(output, 'not_overnight_value') def test_real_world_example(self): fi = FieldInitial( 'sport==hiking,level==beginner', 'hike_for_beginners', 'sport==hiking,level==advanced', 'hike_for_pros', 'sport==hiking', 'hike_for_any', 'sport==climbing,level==beginner', '3-5', 'sport==climbing,level==advanced', '5-8', 'sport==biking', 'pedal' ) # Advanced hiking self.assertEqual( fi.get_value({'sport': 'hiking', 'level': 'advanced'}), 'hike_for_pros' ) # Beginner hiking self.assertEqual( fi.get_value({'sport': 'hiking', 'level': 'beginner'}), 'hike_for_beginners' ) # Hiking on unknown level self.assertEqual( fi.get_value({'sport': 'hiking', 'level': 'elite'}), 'hike_for_any' ) # Hiking but level missing self.assertEqual( fi.get_value({'sport': 'hiking'}), 'hike_for_any' ) # Climbing on unknown level self.assertEqual( fi.get_value({'sport': 'climbing', 'level': 'elite'}), None ) # Biking self.assertEqual( fi.get_value({'sport': 'biking'}), 'pedal' )