class GeotriggerApplicationTestCase(TestCase): """ Tests for the GeotriggerApplication class. """ def setUp(self): self.client_id = 'app_client_id' self.access_token = 'app_access_token' self.client_secret = 'app_client_secret' self.expires_in = 500 self.geotrigger_headers = { 'X-GT-Client-Name': 'geotrigger-python', 'X-GT-Client-Version': __version__, 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + self.access_token } with patch.object(GeotriggerApplication, 'request_token') as mock_request_token: mock_request_token.return_value = { 'access_token': self.access_token, 'expires_in': self.expires_in } with patch.object(GeotriggerSession, 'post') as mock_request: self.client = GeotriggerApplication(self.client_id, self.client_secret) @patch.object(GeotriggerApplication, 'request_token') @patch.object(GeotriggerSession, 'post') def test_request_token(self, mock_post, mock_request_token): """ Test application token requests to ArcGIS Online. """ # App should be registered from setUp app = self.client # Sanity self.assertTrue(app.is_application()) self.assertFalse(app.is_device()) self.assertIsNone(app.device_id) self.assertIsNone(app.refresh_token) # Make sure we set all properties from token response self.assertEqual(app.client_id, self.client_id) self.assertEqual(app.access_token, self.access_token) self.assertEqual(app.client_secret, self.client_secret) self.assertEqual(app.expires_in, self.expires_in) self.assertIsNotNone(app.expires_at) # Ensure `request_token` only called once app.request_token.assert_called_once() # App credentials given, token request should not occur app2 = GeotriggerApplication(self.client_id, self.client_secret, 'access_token', 600) # `request_token` should not have been called self.assertEqual(app2.request_token.call_count, 0) @patch.object(GeotriggerSession, 'post') def test_geotrigger_request(self, mock_request): """ Test creation of Geotrigger API requests. """ # make a call via the `geotrigger_post` method data = {'triggerIds': 'trigger_id'} url = 'trigger/run' self.client.geotrigger_request(url, data=data) # ensure that the `post` method is called with the correct parameters self.client.post.assert_called_once_with( GEOTRIGGER_BASE_URL + url, headers=self.geotrigger_headers, data=json.dumps(data) ) @patch.object(GeotriggerSession, 'post') @patch.object(GeotriggerSession, 'ago_request') def test_refresh(self, mock_ago_request, mock_post): """ Test refresh of expired access tokens. """ first_token = 'new_token' first_expires = 700 second_token = 'newer_token' second_expires = 701 mock_ago_request.return_value = { 'access_token': first_token, 'expires_in': first_expires } old_token = self.client.access_token old_expires = self.client.expires_in # sanity self.assertEqual(self.access_token, old_token) self.assertEqual(self.expires_in, old_expires) # call refresh self.client.refresh() # check refresh request self.client.ago_request.assert_called_once_with( AGO_TOKEN_ROUTE, { 'client_id': self.client_id, 'client_secret': self.client_secret, 'grant_type': 'client_credentials', 'f': 'json' } ) # check refreshed token self.assertEqual(self.client.access_token, first_token) self.assertEqual(self.client.expires_in, first_expires) # make a geotrigger request to ensure that we call refresh again with patch.object(GeotriggerApplication, 'refresh') as mock_refresh: mock_refresh.return_value = { 'access_token': second_token, 'expires_in': second_expires } # force expire credentials self.client.set_expires(0) # sanity self.assertEqual(self.client.refresh.call_count, 0) # make a geotrigger request, which should call refresh self.client.geotrigger_request('dummy/url') # check refresh call count self.assertEqual(self.client.refresh.call_count, 1)