def test_list_shelves_with_offset(self): previouse_shelf_locations = [] request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=1) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) previouse_shelf_locations.append(response.shelves[0].location) # Get next page results and make sure it's not the same as last. request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=2) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) self.assertNotIn(response.shelves[0], previouse_shelf_locations) previouse_shelf_locations.append(response.shelves[0].location) # Get next page results and make sure it's not the same as last 2. request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=3) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) self.assertNotIn(response.shelves[0], previouse_shelf_locations) previouse_shelf_locations.append(response.shelves[0].location)
def test_list_shelves_with_page_token(self): request = shelf_messages.Shelf(enabled=True, page_size=1) response_shelves = [] while True: response = self.service.list_shelves(request) for shelf in response.shelves: self.assertIn(shelf.location, self.shelf_locations) response_shelves.append(shelf) request = shelf_messages.Shelf( enabled=True, page_size=1, page_token=response.page_token) if not response.has_additional_results: break self.assertLen(response_shelves, 3)
def list_shelves(self, request): """List enabled or all shelves based on any shelf attribute.""" self.check_xsrf_token(self.request_state) if request.page_size <= 0: raise endpoints.BadRequestException( 'The value for page_size must be greater than 0.') query, sort_options, returned_fields = ( search_utils.set_search_query_options(request.query)) if not query: query = search_utils.to_query(request, shelf_model.Shelf) offset = search_utils.calculate_page_offset( page_size=request.page_size, page_number=request.page_number) search_results = shelf_model.Shelf.search( query_string=query, query_limit=request.page_size, offset=offset, sort_options=sort_options, returned_fields=returned_fields) total_pages = search_utils.calculate_total_pages( page_size=request.page_size, total_results=search_results.number_found) shelves_messages = [] for document in search_results.results: message = search_utils.document_to_message( document, shelf_messages.Shelf()) message.shelf_request = shelf_messages.ShelfRequest() message.shelf_request.urlsafe_key = document.doc_id message.shelf_request.location = message.location shelves_messages.append(message) return shelf_messages.ListShelfResponse( shelves=shelves_messages, total_results=search_results.number_found, total_pages=total_pages)
def setUp(self): super(ApiUtilsTest, self).setUp() self.test_shelf_model = shelf_model.Shelf( enabled=True, friendly_name='test_friendly_name', location='test_location', lat_long=ndb.GeoPt(10.10, 20.20), altitude=1.1, capacity=10, audit_interval_override=12, audit_notification_enabled=False, audit_requested=True, responsible_for_audit='test_group', last_audit_time=datetime.datetime(year=2018, month=1, day=1), last_audit_by='test_auditer').put().get() self.expected_shelf_message = shelf_messages.Shelf( shelf_request=shelf_messages.ShelfRequest( location='test_location', urlsafe_key=self.test_shelf_model.key.urlsafe()), enabled=True, friendly_name='test_friendly_name', location='test_location', identifier='test_friendly_name', latitude=10.10, longitude=20.20, altitude=1.1, capacity=10, audit_notification_enabled=False, audit_requested=True, responsible_for_audit='test_group', last_audit_time=datetime.datetime(year=2018, month=1, day=1), last_audit_by='test_auditer')
def test_list_shelves_with_search_constraints(self): expressions = shared_messages.SearchExpression(expression='location') expected_response = shelf_messages.ListShelfResponse(shelves=[ shelf_messages.Shelf(location=self.shelf.location, shelf_request=shelf_messages.ShelfRequest( location=self.shelf.location, urlsafe_key=self.shelf.key.urlsafe())) ], total_results=1, total_pages=1) request = shelf_messages.Shelf( query=shared_messages.SearchRequest(query_string='location:NYC', expressions=[expressions], returned_fields=['location'])) response = self.service.list_shelves(request) self.assertEqual(response, expected_response)
def build_shelf_message_from_model(shelf): """Builds a shelf_messages.Shelf ProtoRPC message. Args: shelf: shelf_model.Shelf, the shelf to build a message for. Returns: A shelf_messages.Shelf ProtoRPC message for the given shelf. """ return shelf_messages.Shelf( shelf_request=shelf_messages.ShelfRequest( location=shelf.location, urlsafe_key=shelf.key.urlsafe()), enabled=shelf.enabled, friendly_name=shelf.friendly_name, location=shelf.location, latitude=shelf.latitude, longitude=shelf.longitude, altitude=shelf.altitude, capacity=shelf.capacity, audit_notification_enabled=shelf.audit_notification_enabled, audit_requested=shelf.audit_requested, responsible_for_audit=shelf.responsible_for_audit, last_audit_time=shelf.last_audit_time, last_audit_by=shelf.last_audit_by, )
def list_shelves(self, request): """List enabled or all shelves based on any shelf attribute.""" self.check_xsrf_token(self.request_state) query, sort_options, returned_fields = ( search_utils.set_search_query_options(request.query)) if not query: query = search_utils.to_query(request, shelf_model.Shelf) cursor = search_utils.get_search_cursor(request.page_token) search_results = shelf_model.Shelf.search( query_string=query, query_limit=request.page_size, cursor=cursor, sort_options=sort_options, returned_fields=returned_fields) new_search_cursor = None if search_results.cursor: new_search_cursor = search_results.cursor.web_safe_string shelves_messages = [] for document in search_results.results: message = search_utils.document_to_message(document, shelf_messages.Shelf()) message.shelf_request = shelf_messages.ShelfRequest() message.shelf_request.urlsafe_key = document.doc_id message.shelf_request.location = message.location shelves_messages.append(message) return shelf_messages.ListShelfResponse( shelves=shelves_messages, additional_results=bool(new_search_cursor), page_token=new_search_cursor)
def test_list_devices_with_shelf_filter(self, mock_get_shelf): # Test for shelf location as filter. mock_get_shelf.return_value = self.shelf shelf_request_message = shelf_messages.ShelfRequest( location=self.shelf.location) message = shelf_messages.Shelf(shelf_request=shelf_request_message) request = device_messages.Device(shelf=message) response = self.service.list_devices(request) mock_get_shelf.assert_called_once_with(shelf_request_message) self.assertEqual(len(response.devices), 2)
def test_to_dict(self): """Test that a dictionary is build from a ProtoRPC message.""" message = shelf_messages.Shelf( location='NY', capacity=50, friendly_name='The_Big_Apple', audit_requested=False, responsible_for_audit='daredevils', last_audit_by=loanertest.USER_EMAIL, enabled=True) expected_dict = { 'location': 'NY', 'capacity': 50, 'friendly_name': 'The_Big_Apple', 'audit_requested': False, 'responsible_for_audit': 'daredevils', 'last_audit_by': loanertest.USER_EMAIL, 'enabled': True} filters = api_utils.to_dict(message, shelf_model.Shelf) self.assertEqual(filters, expected_dict)
def test_document_to_message(self, mock_logging): """Tests the creation of a protorpc message from a search document.""" test_search_document = search.ScoredDocument( doc_id='test_doc_id', fields=[ search.NumberField(name='capacity', value=20.0), search.TextField(name='location', value='US MTV'), search.AtomField(name='location', value='US-MTV'), search.AtomField(name='enabled', value='True'), search.GeoField(name='lat_long', value=search.GeoPoint(52.37, 4.88)), search.TextField(name='not_present', value='MTV') ]) expected_message = shelf_messages.Shelf(enabled=True, location='US-MTV', capacity=20, latitude=52.37, longitude=4.88) response_message = search_utils.document_to_message( test_search_document, shelf_messages.Shelf()) self.assertEqual(response_message, expected_message) self.assertTrue(response_message.enabled) assert mock_logging.error.call_count == 1
def testShelf(self): last_audit_date = datetime.datetime.now() shelf = shelf_messages.Shelf(enabled=True, friendly_name='FAKE-FRIENDLY-NAME', location='FAKE-LOCATION', identifier='FAKE-IDENTIFIER', latitude=20.45, longitude=30.85, altitude=25.3, capacity=10, audit_notification_enabled=True, audit_requested=False, responsible_for_audit='FAKE-AUDIT-PERSON', last_audit_time=last_audit_date, last_audit_by='FAKE-LAST-AUDIT-PERSON', page_token='FAKE-PAGE-TOKEN', page_size=50, audit_interval_override=20, audit_enabled=True) self.assertTrue(shelf.enabled) self.assertTrue(shelf.audit_enabled) self.assertFalse(shelf.audit_requested) self.assertTrue(shelf.audit_notification_enabled) self.assertEqual(shelf.capacity, 10) self.assertEqual(shelf.page_size, 50) self.assertEqual(shelf.altitude, 25.3) self.assertEqual(shelf.latitude, 20.45) self.assertEqual(shelf.longitude, 30.85) self.assertEqual(shelf.audit_interval_override, 20) self.assertEqual(shelf.last_audit_time, last_audit_date) self.assertEqual(shelf.location, 'FAKE-LOCATION') self.assertEqual(shelf.identifier, 'FAKE-IDENTIFIER') self.assertEqual(shelf.page_token, 'FAKE-PAGE-TOKEN') self.assertEqual(shelf.friendly_name, 'FAKE-FRIENDLY-NAME') self.assertEqual(shelf.last_audit_by, 'FAKE-LAST-AUDIT-PERSON') self.assertEqual(shelf.responsible_for_audit, 'FAKE-AUDIT-PERSON')
class SearchTest(loanertest.EndpointsTestCase, parameterized.TestCase): _ASSIGNED_DATE = datetime.datetime(year=2017, month=1, day=1) @parameterized.parameters(( shelf_messages.Shelf(location='NY', capacity=50), 'location:NY capacity:50 enabled:True', ), ( shelf_messages.Shelf(location='NY', capacity=50, enabled=False), 'location:NY capacity:50 enabled:False', )) def test_to_query(self, message, expected_query): """Tests the creation of a valid search query from ndb properties.""" query = search_utils.to_query(message, shelf_model.Shelf) # The query is split because ndb properties are unordered when called by # model_class._properties. This test would be flaky otherwise. self.assertCountEqual(query.split(' '), expected_query.split(' ')) @parameterized.named_parameters( ('Shelf Message', shelf_messages.Shelf(), search.ScoredDocument( doc_id='test_doc_id', fields=[ search.NumberField(name='capacity', value=20.0), search.TextField(name='location', value='US MTV'), search.AtomField(name='location', value='US-MTV'), search.AtomField(name='enabled', value='True'), search.GeoField(name='lat_long', value=search.GeoPoint(52.37, 4.88)), search.TextField(name='not_present', value='MTV') ]), shelf_messages.Shelf(enabled=True, location='US-MTV', capacity=20, latitude=52.37, longitude=4.88), 1), ('Device Message', device_messages.Device(), search.ScoredDocument( doc_id='test_doc_id', fields=[ search.DateField(name='assignment_date', value=_ASSIGNED_DATE), search.TextField(name='serial_number', value='1234'), search.AtomField(name='enrolled', value='True'), search.TextField(name='assigned_user', value='user') ]), device_messages.Device( enrolled=True, serial_number='1234', assigned_user='******', max_extend_date=_ASSIGNED_DATE + datetime.timedelta(days=14), assignment_date=_ASSIGNED_DATE), 0)) def test_document_to_message(self, message, test_search_document, expected_message, log_call_count): """Tests the creation of a protorpc message from a search document.""" with mock.patch.object(search_utils, 'logging', autospec=True) as mock_logging: response_message = search_utils.document_to_message( test_search_document, message) self.assertEqual(response_message, expected_message) self.assertEqual(mock_logging.error.call_count, log_call_count) def test_calculate_page_offset(self): """Tests the calculation of page offset.""" page_size = 10 page_number = 5 offset = search_utils.calculate_page_offset(page_size, page_number) self.assertEqual(40, offset) def test_calculate_total_pages(self): """Tests the calculation of total pages.""" page_size = 6 total_results = 11 total_pages = search_utils.calculate_total_pages( page_size, total_results) self.assertEqual(2, total_pages) @parameterized.named_parameters( { 'testcase_name': 'QueryStringOnly', 'request': shared_messages.SearchRequest(query_string='enrolled:True'), 'expected_values': ('enrolled:True', None, []) }, { 'testcase_name': 'QueryStringWithReturnedFields', 'request': shared_messages.SearchRequest(query_string='location:US-NYC', returned_fields=['location']), 'expected_values': ('location:US-NYC', None, ['location']) }, ) def test_set_search_query_options(self, request, expected_values): """Tests setting the query options without sort options from message.""" returned_query, returned_sort_options, returned_returned_fields = ( search_utils.set_search_query_options(request)) expected_query, expected_sort_options, expcted_returned_fields = ( expected_values) self.assertEqual(expected_sort_options, returned_sort_options) self.assertEqual(expected_query, returned_query) self.assertEqual(expcted_returned_fields, returned_returned_fields) @parameterized.named_parameters( { 'testcase_name': 'ExpressionWithDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression( expression='enrolled', direction=shared_messages.SortDirection.ASCENDING) ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.ASCENDING) ] }, { 'testcase_name': 'MultipleExpressionsWithDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression( expression='enrolled', direction=shared_messages.SortDirection.ASCENDING), shared_messages.SearchExpression( expression='serial_number', direction=shared_messages.SortDirection.DESCENDING) ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.ASCENDING), search.SortExpression( expression='serial_number', direction=search.SortExpression.DESCENDING) ] }, { 'testcase_name': 'ExpressionWithoutDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression(expression='enrolled') ]), 'expected_sort_options_expressions': [search.SortExpression(expression='enrolled')] }, { 'testcase_name': 'MultipleExpressionsWithoutDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression(expression='enrolled'), shared_messages.SearchExpression( expression='serial_number') ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.DESCENDING), search.SortExpression( expression='serial_number', direction=search.SortExpression.DESCENDING) ] }, ) def test_set_search_query_options_with_sort_options( self, request, expected_sort_options_expressions): """Tests setting query options with sort options from message.""" returned_query, returned_sort_options, returned_returned_fields = ( search_utils.set_search_query_options(request)) del returned_query # Unused. del returned_returned_fields # Unused. for i in range(len(returned_sort_options.expressions)): self.assertEqual(returned_sort_options.expressions[i].expression, expected_sort_options_expressions[i].expression) self.assertEqual(returned_sort_options.expressions[i].direction, expected_sort_options_expressions[i].direction)
class ApiUtilsTest(parameterized.TestCase, loanertest.TestCase): def setUp(self): super(ApiUtilsTest, self).setUp() self.test_shelf_model = shelf_model.Shelf( enabled=True, friendly_name='test_friendly_name', location='test_location', lat_long=ndb.GeoPt(10.10, 20.20), altitude=1.1, capacity=10, audit_interval_override=12, audit_notification_enabled=False, audit_requested=True, responsible_for_audit='test_group', last_audit_time=datetime.datetime(year=2018, month=1, day=1), last_audit_by='test_auditer').put().get() self.expected_shelf_message = shelf_messages.Shelf( shelf_request=shelf_messages.ShelfRequest( location='test_location', urlsafe_key=self.test_shelf_model.key.urlsafe()), enabled=True, friendly_name='test_friendly_name', location='test_location', identifier='test_friendly_name', latitude=10.10, longitude=20.20, altitude=1.1, capacity=10, audit_notification_enabled=False, audit_requested=True, responsible_for_audit='test_group', last_audit_time=datetime.datetime(year=2018, month=1, day=1), last_audit_by='test_auditer') def test_build_device_message_from_model(self): """Test the construction of a device message from a device entity.""" test_device = device_model.Device( serial_number='test_serial_value', asset_tag='test_asset_tag_value', enrolled=True, device_model='test model value', due_date=datetime.datetime(year=2018, month=1, day=1), last_known_healthy=datetime.datetime(year=2018, month=1, day=2), shelf=self.test_shelf_model.key, assigned_user='******', assignment_date=datetime.datetime(year=2018, month=1, day=3), current_ou=constants.ORG_UNIT_DICT['GUEST'], ou_changed_date=datetime.datetime(year=2018, month=1, day=4), locked=True, lost=False, mark_pending_return_date=datetime.datetime(year=2018, month=1, day=5), chrome_device_id='device id value', last_heartbeat=datetime.datetime(year=2018, month=1, day=6), damaged=None, damaged_reason='Not damaged', last_reminder=device_model.Reminder(level=1), next_reminder=device_model.Reminder(level=2), ).put().get() expected_message = device_messages.Device( serial_number='test_serial_value', asset_tag='test_asset_tag_value', identifier='test_asset_tag_value', enrolled=True, device_model='test model value', due_date=datetime.datetime(year=2018, month=1, day=1), last_known_healthy=datetime.datetime(year=2018, month=1, day=2), shelf=self.expected_shelf_message, assigned_user='******', assignment_date=datetime.datetime(year=2018, month=1, day=3), current_ou=constants.ORG_UNIT_DICT['GUEST'], ou_changed_date=datetime.datetime(year=2018, month=1, day=4), locked=True, lost=False, mark_pending_return_date=datetime.datetime(year=2018, month=1, day=5), chrome_device_id='device id value', last_heartbeat=datetime.datetime(year=2018, month=1, day=6), damaged=None, damaged_reason='Not damaged', last_reminder=device_messages.Reminder(level=1), next_reminder=device_messages.Reminder(level=2), guest_permitted=True, guest_enabled=True, max_extend_date=test_device.return_dates.max, overdue=True, ) actual_message = api_utils.build_device_message_from_model( test_device, True) self.assertEqual(actual_message, expected_message) @parameterized.parameters( (1, datetime.datetime(year=2018, month=1, day=1), 2), (3, datetime.datetime(year=2017, month=4, day=2), None), (5, None, 6), ) def test_build_reminder_message_from_model(self, test_level, test_datetime, test_count): """Test the construction of a reminder message from a reminder entity.""" test_reminder = device_model.Reminder(level=test_level, time=test_datetime, count=test_count).put().get() expected_message = device_messages.Reminder(level=test_level, time=test_datetime, count=test_count) returned_message = api_utils.build_reminder_message_from_model( test_reminder) self.assertEqual(returned_message, expected_message) def test_build_shelf_message_from_model(self): """Test the construction of a shelf message from a shelf entitiy.""" actual_message = api_utils.build_shelf_message_from_model( self.test_shelf_model) self.assertEqual(actual_message, self.expected_shelf_message) @parameterized.named_parameters( { 'testcase_name': 'with_lat_long', 'message': shelf_messages.Shelf(location='NY', capacity=50, friendly_name='Big_Apple', audit_requested=False, responsible_for_audit='daredevils', latitude=12.5, longitude=12.5, last_audit_by=loanertest.USER_EMAIL, enabled=True), 'expected_dict': { 'location': 'NY', 'capacity': 50, 'friendly_name': 'Big_Apple', 'audit_requested': False, 'responsible_for_audit': 'daredevils', 'lat_long': ndb.GeoPt(12.5, 12.5), 'last_audit_by': loanertest.USER_EMAIL, 'enabled': True }, }, { 'testcase_name': 'without_lat_long', 'message': shelf_messages.Shelf(location='NY'), 'expected_dict': { 'location': 'NY', 'enabled': True }, }) def test_to_dict(self, message, expected_dict): """Test that a dictionary is build from a ProtoRPC message.""" filters = api_utils.to_dict(message, shelf_model.Shelf) self.assertEqual(filters, expected_dict) def test_get_ndb_key_not_found(self): """Test the get of an ndb.Key, raises endpoints.BadRequestException.""" with self.assertRaisesRegexp(endpoints.BadRequestException, api_utils._CORRUPT_KEY_MSG): api_utils.get_ndb_key('corruptKey') def test_get_datastore_cursor_not_found(self): """Test the get of a datastore.Cursor, raises endpoints.BadRequestException. """ with self.assertRaisesRegexp(endpoints.BadRequestException, api_utils._MALFORMED_PAGE_TOKEN_MSG): api_utils.get_datastore_cursor('malformedPageToken')
class ShelfApiTest(parameterized.TestCase, loanertest.EndpointsTestCase): """Test for the Shelf API.""" def setUp(self): super(ShelfApiTest, self).setUp() self.patcher_directory = mock.patch( '__main__.device_model.directory.DirectoryApiClient') self.mock_directoryclass = self.patcher_directory.start() self.addCleanup(self.patcher_directory.stop) self.service = shelf_api.ShelfApi() self.login_admin_endpoints_user() self.patcher_xsrf = mock.patch( '__main__.shelf_api.root_api.Service.check_xsrf_token') self.shelf = shelf_model.Shelf.enroll(user_email=loanertest.USER_EMAIL, location='NYC', capacity=10, friendly_name='GnG', latitude=40.6892534, longitude=-74.0466891, altitude=1.0) shelf1 = shelf_model.Shelf.enroll(user_email=loanertest.USER_EMAIL, location='MTV', capacity=20) shelf2 = shelf_model.Shelf.enroll(user_email=loanertest.USER_EMAIL, location='SAO', capacity=10) self.disabled_shelf = shelf_model.Shelf.enroll( user_email=loanertest.USER_EMAIL, location='SVL', capacity=10, friendly_name='Bay') self.disabled_shelf.disable(loanertest.USER_EMAIL) self.shelf_locations = [ self.shelf.location, shelf1.location, shelf2.location, self.disabled_shelf.location ] self.device1_key = device_model.Device( serial_number='12345', enrolled=True, device_model='HP Chromebook 13 G1', current_ou='/', chrome_device_id='unique_id_1', damaged=False, ).put() self.device2_key = device_model.Device( serial_number='54321', enrolled=True, device_model='HP Chromebook 13 G1', current_ou='/', chrome_device_id='unique_id_2', damaged=False, ).put() self.device3_key = device_model.Device( serial_number='67890', enrolled=True, shelf=self.shelf.key, device_model='HP Chromebook 13 G1', current_ou='/', chrome_device_id='unique_id_3', damaged=False, ).put() self.device4_key = device_model.Device( serial_number='ABC123', enrolled=True, shelf=self.shelf.key, device_model='HP Chromebook 13 G1', current_ou='/', chrome_device_id='unique_id_4', damaged=False, ).put() self.device_identifiers = [ self.device1_key.get().serial_number, self.device2_key.get().serial_number, self.device3_key.get().serial_number ] def tearDown(self): super(ShelfApiTest, self).tearDown() self.service = None @mock.patch('__main__.root_api.Service.check_xsrf_token') @mock.patch('__main__.shelf_model.Shelf.enroll') def test_enroll(self, mock_enroll, mock_xsrf_token): """Test Enroll with mock methods.""" request = shelf_messages.EnrollShelfRequest( location='nyc', capacity=100, friendly_name='test', latitude=12.5, longitude=12.5, altitude=2.0, responsible_for_audit='precise', audit_interval_override=33, audit_notification_enabled=True) response = self.service.enroll(request) assert mock_xsrf_token.call_count == 1 self.assertIsInstance(response, message_types.VoidMessage) def test_enroll_bad_request(self): request = shelf_messages.EnrollShelfRequest(capacity=10) with self.assertRaisesRegexp(shelf_api.endpoints.BadRequestException, 'Entity has uninitialized properties'): self.service.enroll(request) request = shelf_messages.EnrollShelfRequest(location='nyc', capacity=10, latitude=12.5) with self.assertRaisesRegexp(shelf_api.endpoints.BadRequestException, shelf_model._LAT_LONG_MSG): self.service.enroll(request) @mock.patch('__main__.root_api.Service.check_xsrf_token') def test_get_by_location(self, mock_xsrf_token): request = shelf_messages.ShelfRequest(location='NYC') response = self.service.get(request) assert mock_xsrf_token.call_count == 1 self.assertEqual(self.shelf.location, response.location) self.assertEqual(self.shelf.friendly_name, response.friendly_name) def test_disable_by_location(self): request = shelf_messages.ShelfRequest(location='NYC') self.assertTrue(self.shelf.enabled) response = self.service.disable(request) self.assertFalse(self.shelf.enabled) self.assertIsInstance(response, message_types.VoidMessage) @mock.patch('__main__.root_api.Service.check_xsrf_token') def test_update_using_location(self, mock_xsrf_token): request = shelf_messages.UpdateShelfRequest( shelf_request=shelf_messages.ShelfRequest(location='NYC'), location='NYC-9th') response = self.service.update(request) assert mock_xsrf_token.call_count == 1 self.assertEqual(self.shelf.location, 'NYC-9th') shelf = shelf_model.Shelf.get(friendly_name='GnG') self.assertEqual(shelf.location, 'NYC-9th') self.assertIsInstance(response, message_types.VoidMessage) @parameterized.parameters(( shelf_messages.Shelf(capacity=10), 2, ), ( shelf_messages.Shelf(enabled=False), 1, ), ( shelf_messages.Shelf(query=shared_messages.SearchRequest( query_string='enabled:True capacity:10')), 2, ), ( shelf_messages.Shelf(query=shared_messages.SearchRequest( query_string='enabled:False')), 1, )) @mock.patch('__main__.root_api.Service.check_xsrf_token') def test_list_shelves(self, request, response_length, mock_xsrf_token): response = self.service.list_shelves(request) assert mock_xsrf_token.call_count == 1 self.assertEqual(response_length, len(response.shelves)) def test_list_shelves_invalid_page_size(self): with self.assertRaises(endpoints.BadRequestException): request = shelf_messages.Shelf(page_size=0) self.service.list_shelves(request) def test_list_shelves_with_search_constraints(self): expressions = shared_messages.SearchExpression(expression='location') expected_response = shelf_messages.ListShelfResponse(shelves=[ shelf_messages.Shelf(location=self.shelf.location, shelf_request=shelf_messages.ShelfRequest( location=self.shelf.location, urlsafe_key=self.shelf.key.urlsafe())) ], total_results=1, total_pages=1) request = shelf_messages.Shelf( query=shared_messages.SearchRequest(query_string='location:NYC', expressions=[expressions], returned_fields=['location'])) response = self.service.list_shelves(request) self.assertEqual(response, expected_response) def test_list_shelves_with_offset(self): previouse_shelf_locations = [] request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=1) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) previouse_shelf_locations.append(response.shelves[0].location) # Get next page results and make sure it's not the same as last. request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=2) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) self.assertNotIn(response.shelves[0], previouse_shelf_locations) previouse_shelf_locations.append(response.shelves[0].location) # Get next page results and make sure it's not the same as last 2. request = shelf_messages.Shelf(enabled=True, page_size=1, page_number=3) response = self.service.list_shelves(request) self.assertEqual(len(response.shelves), 1) self.assertNotIn(response.shelves[0], previouse_shelf_locations) previouse_shelf_locations.append(response.shelves[0].location) @mock.patch('__main__.root_api.Service.check_xsrf_token') @mock.patch('__main__.shelf_api.logging.info') def test_audit_using_shelf_location(self, mock_logging, mock_xsrf_token): request = shelf_messages.ShelfAuditRequest( shelf_request=shelf_messages.ShelfRequest(location='NYC'), device_identifiers=self.device_identifiers) response = self.service.audit(request) assert mock_xsrf_token.call_count == 1 mock_logging.assert_called() for identifier in self.device_identifiers: datastore_device = device_model.Device.get( serial_number=identifier) self.assertEqual(datastore_device.shelf.get().location, 'NYC') self.assertFalse(self.shelf.audit_requested) self.assertEqual(self.shelf.last_audit_by, loanertest.SUPER_ADMIN_EMAIL) self.assertIsInstance(response, message_types.VoidMessage) def test_audit_invalid_device(self): request = shelf_messages.ShelfAuditRequest( shelf_request=shelf_messages.ShelfRequest(location='NYC'), device_identifiers=['Invalid']) with self.assertRaisesRegexp( endpoints.NotFoundException, shelf_api._DEVICE_DOES_NOT_EXIST_MSG % 'Invalid'): self.service.audit(request) @mock.patch.object(device_model.Device, 'search') @mock.patch.object(shelf_api, 'get_shelf', autospec=True) def test_audit_remove_devices(self, mock_get_shelf, mock_model_device_search): shelf = self.device2_key.get() shelf.shelf = self.shelf.key shelf.put() mock_model_device_search.return_value = (search.SearchResults( results=[ search.ScoredDocument(doc_id=self.device2_key.urlsafe()), search.ScoredDocument(doc_id=self.device3_key.urlsafe()), search.ScoredDocument(doc_id=self.device4_key.urlsafe()) ], number_found=3)) mock_get_shelf.return_value = self.shelf request = shelf_messages.ShelfAuditRequest( shelf_request=shelf_messages.ShelfRequest( location=self.shelf.location), device_identifiers=[self.device3_key.get().serial_number]) self.service.audit(request) self.assertEqual(self.device3_key.get().shelf, self.shelf.key) self.assertEqual(self.device2_key.get().shelf, None) self.assertEqual(self.device4_key.get().shelf, None) def test_get_shelf_urlsafe_key(self): """Test getting a shelf using the urlsafe key.""" request = shelf_messages.ShelfRequest( urlsafe_key=self.shelf.key.urlsafe()) shelf = shelf_api.get_shelf(request) self.assertEqual(shelf, self.shelf) def test_get_shelf_using_location(self): """Test getting a shelf using the location.""" request = shelf_messages.ShelfRequest(location=self.shelf.location) shelf = shelf_api.get_shelf(request) self.assertEqual(shelf, self.shelf) def test_get_shelf_using_location_error(self): """Test getting a shelf with an invalid location.""" request = shelf_messages.ShelfRequest(location='Not_Valid') with self.assertRaisesRegexp( endpoints.NotFoundException, shelf_api._SHELF_DOES_NOT_EXIST_MSG % request.location): shelf_api.get_shelf(request)
def test_list_shelves_invalid_page_size(self): with self.assertRaises(endpoints.BadRequestException): request = shelf_messages.Shelf(page_size=0) self.service.list_shelves(request)
class SearchTest(loanertest.EndpointsTestCase, parameterized.TestCase): @parameterized.parameters(( shelf_messages.Shelf(location='NY', capacity=50), 'location:NY capacity:50 enabled:True', ), ( shelf_messages.Shelf(location='NY', capacity=50, enabled=False), 'location:NY capacity:50 enabled:False', )) def test_to_query(self, message, expected_query): """Tests the creation of a valid search query from ndb properties.""" query = search_utils.to_query(message, shelf_model.Shelf) # The query is split because ndb properties are unordered when called by # model_class._properties. This test would be flaky otherwise. self.assertCountEqual(query.split(' '), expected_query.split(' ')) @mock.patch.object(search_utils, 'logging', autospec=True) def test_document_to_message(self, mock_logging): """Tests the creation of a protorpc message from a search document.""" test_search_document = search.ScoredDocument( doc_id='test_doc_id', fields=[ search.NumberField(name='capacity', value=20.0), search.TextField(name='location', value='US MTV'), search.AtomField(name='location', value='US-MTV'), search.AtomField(name='enabled', value='True'), search.GeoField(name='lat_long', value=search.GeoPoint(52.37, 4.88)), search.TextField(name='not_present', value='MTV') ]) expected_message = shelf_messages.Shelf(enabled=True, location='US-MTV', capacity=20, latitude=52.37, longitude=4.88) response_message = search_utils.document_to_message( test_search_document, shelf_messages.Shelf()) self.assertEqual(response_message, expected_message) self.assertTrue(response_message.enabled) assert mock_logging.error.call_count == 1 def test_get_search_cursor(self): """Tests the creation of a search cursor with a web_safe_string.""" expected_cursor_web_safe_string = 'False:ODUxODBhNTgyYTQ2ZmI0MDU' returned_cursor = ( search_utils.get_search_cursor(expected_cursor_web_safe_string)) self.assertEqual(expected_cursor_web_safe_string, returned_cursor.web_safe_string) @mock.patch.object(search, 'Cursor', autospec=True) def test_get_search_cursor_error(self, mock_cursor): """Tests the creation of a search cursor when an error occurs.""" mock_cursor.side_effect = ValueError with self.assertRaisesWithLiteralMatch(endpoints.BadRequestException, search_utils._CORRUPT_KEY_MSG): search_utils.get_search_cursor(None) @parameterized.named_parameters( { 'testcase_name': 'QueryStringOnly', 'request': shared_messages.SearchRequest(query_string='enrolled:True'), 'expected_values': ('enrolled:True', None, []) }, { 'testcase_name': 'QueryStringWithReturnedFields', 'request': shared_messages.SearchRequest(query_string='location:US-NYC', returned_fields=['location']), 'expected_values': ('location:US-NYC', None, ['location']) }, ) def test_set_search_query_options(self, request, expected_values): """Tests setting the query options without sort options from message.""" returned_query, returned_sort_options, returned_returned_fields = ( search_utils.set_search_query_options(request)) expected_query, expected_sort_options, expcted_returned_fields = ( expected_values) self.assertEqual(expected_sort_options, returned_sort_options) self.assertEqual(expected_query, returned_query) self.assertEqual(expcted_returned_fields, returned_returned_fields) @parameterized.named_parameters( { 'testcase_name': 'ExpressionWithDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression( expression='enrolled', direction=shared_messages.SortDirection.ASCENDING) ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.ASCENDING) ] }, { 'testcase_name': 'MultipleExpressionsWithDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression( expression='enrolled', direction=shared_messages.SortDirection.ASCENDING), shared_messages.SearchExpression( expression='serial_number', direction=shared_messages.SortDirection.DESCENDING) ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.ASCENDING), search.SortExpression( expression='serial_number', direction=search.SortExpression.DESCENDING) ] }, { 'testcase_name': 'ExpressionWithoutDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression(expression='enrolled') ]), 'expected_sort_options_expressions': [search.SortExpression(expression='enrolled')] }, { 'testcase_name': 'MultipleExpressionsWithoutDirection', 'request': shared_messages.SearchRequest( query_string='enrolled:True', expressions=[ shared_messages.SearchExpression(expression='enrolled'), shared_messages.SearchExpression( expression='serial_number') ]), 'expected_sort_options_expressions': [ search.SortExpression( expression='enrolled', direction=search.SortExpression.DESCENDING), search.SortExpression( expression='serial_number', direction=search.SortExpression.DESCENDING) ] }, ) def test_set_search_query_options_with_sort_options( self, request, expected_sort_options_expressions): """Tests setting query options with sort options from message.""" returned_query, returned_sort_options, returned_returned_fields = ( search_utils.set_search_query_options(request)) del returned_query # Unused. del returned_returned_fields # Unused. for i in range(len(returned_sort_options.expressions)): self.assertEqual(returned_sort_options.expressions[i].expression, expected_sort_options_expressions[i].expression) self.assertEqual(returned_sort_options.expressions[i].direction, expected_sort_options_expressions[i].direction)