def test_add_missing_parents_on_pull(self): root_post_data, _ = self.posts_native_data[0] post_data, _ = self.posts_native_data[1] fbs = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', posts_tracking_enabled=True) root_post = self._create_db_post(root_post_data['_wrapped_data']['message'], channel=fbs, facebook=root_post_data) conv = Conversation.objects.get() conv.delete() root_post.reload() self.assertEqual(Conversation.objects(posts=root_post.id).count(), 0) post = self._create_db_post(post_data['_wrapped_data']['message'], channel=fbs, facebook=post_data) self.login(user=self.user) requests = mock.MagicMock() params = {'channel': str(fbs.id), 'limit': 10, 'reserve_time': 30, 'mode': 'conversation', 'token': self.auth_token} from solariat.tests.base import LoggerInterceptor with mock.patch.dict('sys.modules', {'requests': requests}), LoggerInterceptor() as logs: response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') # root post was in database, # so it should be added without marking conversation as corrupted requests.get.assert_not_called() found_parent_msgs = [log.message for log in logs if 'Found parent post' in log.message] assert len(found_parent_msgs) == 1 conv.reload() self.assertFalse(conv.is_corrupted) # clean database and create conversation with post without parent post Conversation.objects.coll.remove() FacebookPost.objects.coll.remove() QueueMessage.objects.coll.remove() post = self._create_db_post(post_data['_wrapped_data']['message'], channel=fbs, facebook=post_data) with mock.patch.dict('sys.modules', {'requests': requests}): response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') self.assertEqual(requests.request.call_count, 1) conv.reload() self.assertTrue(conv.is_corrupted) # simulate recovery of root post post = self._create_db_post(root_post_data['_wrapped_data']['message'], channel=fbs, facebook=root_post_data) conv.reload() self.assertFalse(conv.is_corrupted)
def test_destroy_status(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), object_id="test_status_id", message_type="Status") data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/destroy_message', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 1) self.assertEqual(LOGGED_ACTIONS[0], ('destroy_status', (), { 'id': u'test_status_id' })) post_data['message_type'] = "DirectMessage" data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/destroy_message', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 2) self.assertEqual(LOGGED_ACTIONS[1], ('destroy_direct_message', (), { 'id': u'test_status_id' }))
def test_post_and_comment(self): token = self.get_token() self.assertEqual(QueueMessage.objects.count(), 0) self.assertEqual(FacebookPost.objects.count(), 0) self.assertEqual(Conversation.objects.count(), 0) params = dict(content="Test creating root post", channel=str(self.inbound.id), token=token) response = self.client.post(get_api_url('stubs/facebook/create_post'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') self.assertEqual(response.status_code, 200) self.assertEqual(FacebookPost.objects.count(), 1) self.assertEqual(Conversation.objects.count(), 1) self.assertEqual(QueueMessage.objects.count(), 1) created_post = FacebookPost.objects.find_one() params = dict(content="Test creating another root post", channel=str(self.inbound.id), parent=str(created_post.native_id), token=token) response = self.client.post( get_api_url('stubs/facebook/create_comment'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') self.assertEqual(response.status_code, 200) self.assertEqual(FacebookPost.objects.count(), 2) self.assertEqual(Conversation.objects.count(), 1) self.assertEqual(QueueMessage.objects.count(), 2)
def test_update_with_media(self): from StringIO import StringIO as FileBuffer token = self.get_token() status = 'This is some test api status with media' image = 'image content' file_obj = (FileBuffer(image), 'image.jpg') post_data = dict(token=token, channel=str(self.channel.id), status=status, media=file_obj) resp = self.client.post(get_api_url( 'commands/twitter/update_with_media', version='v2.0'), buffered=True, content_type='multipart/form-data', data=post_data, base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertEqual(len(LOGGED_ACTIONS), 2) method_name, args, kwargs = LOGGED_ACTIONS[0] self.assertEqual(method_name, 'media_upload') self.assertEqual( args, (file_obj[1], )) # first argument to update_with_media is filename stream = kwargs['file'] self.assertIsNotNone(stream) #self.assertEqual(stream.read(), image) self.assertNotIn('media', kwargs) method_name, args, kwargs = LOGGED_ACTIONS[1] self.assertEqual(method_name, 'update_status') self.assertEqual(status, kwargs['status']) self.assertIsNone(kwargs['in_reply_to_status_id'])
def test_auth_media(self): import requests from solariat_bottle.tests.social.test_twitter_rate_limits import fake_download_media_success_response token = self.get_token() post_data = dict( token=token, channel=str(self.channel.id), media_url="https://ton.twitter.com/1.1/ton/data/dm/5/5/q.png", data_uri=True) data = json.dumps(post_data) with patch.object(requests, 'get') as mock: mock.return_value = fake_download_media_success_response() resp = self.client.get(get_api_url('commands/twitter/auth_media', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(mock.call_count, 1, "Must have been called once") self.assertEqual(mock.call_args[0][0], post_data['media_url']) self.assertEqual(resp.status_code, 200) resp = json.loads(resp.data) self.assertIn('item', resp) self.assertIn('media_data', resp['item']) self.assertIn('twitter_response_headers', resp['item'])
def test_delete_object(self): wrapped = dict(type="status", source_id="fakeid", source_type="page", page_id="12345") fb = dict(_wrapped_data=wrapped, facebook_post_id="12345_54321") post = self._create_db_post(content='Test fb post', channel=self.channel, facebook=fb) post.extra_fields = dict(facebook=dict(_wrapped_data=dict(source_type='Page', source_id='sourceid'))) post._native_id = 'test_profile_id' post.save() self.channel.facebook_pages = [dict(id='sourceid', access_token='dummy_token')] self.channel.save() token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), target_id='test_profile_id') data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/delete_object', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_OBJECTS) == 1) self.assertTrue(len(FB_REQUESTS) == 0) self.assertEqual(FB_OBJECTS[0], ('delete_object', (u'test_profile_id',), {}))
def test_missing_parent_for_comment__deleted_channel(self): root_post_data = self.public_conversation_data[0] comment_data = self.public_conversation_data[1] # first comment facebook_handle_id = self.lisa['id'] facebook_page_ids = ["998309733582959", "297414983930888"] fbs1 = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', facebook_handle_id=facebook_handle_id, facebook_page_ids=facebook_page_ids, posts_tracking_enabled=True) root_post = self._create_db_post(root_post_data['_wrapped_data']['message'], channel=fbs1, facebook=root_post_data, user_profile=self.will) fbs1.archive() conv1 = Conversation.objects.get(posts=root_post.id) self.assertRaises(Channel.DoesNotExist, lambda: conv1.service_channel) fbs2 = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', facebook_handle_id=facebook_handle_id, facebook_page_ids=facebook_page_ids, posts_tracking_enabled=True) self.login(user=self.user) requests = mock.MagicMock() params = {'channel': str(fbs2.id), 'limit': 10, 'reserve_time': 30, 'mode': 'root_included', 'token': self.auth_token} from solariat.tests.base import LoggerInterceptor with mock.patch.dict('sys.modules', {'requests': requests}), LoggerInterceptor() as logs: # adding comment to another channel comment = self._create_db_post(comment_data['_wrapped_data']['message'], channel=fbs2, facebook=comment_data, user_profile=self.lisa) conv2 = Conversation.objects.get(posts=comment.id) self.assertNotEqual(conv1.id, conv2.id) self.assertNotEqual(conv1.channels, conv2.channels) response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') # root post was in database, # so it should be added without marking conversation as corrupted requests.get.assert_not_called() found_parent_msgs = [log.message for log in logs if 'Found parent post' in log.message] assert len(found_parent_msgs) == 1 conv2.reload() self.assertFalse(conv2.is_corrupted) data = json.loads(response.data) self.assertEqual([p['id'] for p in data['data'][0]['post_data']], [root_post.id, comment.id])
def rpc(self, path, **kw): resp = self.client.get(get_api_url(path, version='v2.0'), data=json.dumps(kw), content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200, msg="HTTP code %s: %s" % (resp.status_code, resp.data)) return json.loads(resp.data)['item']
def _fetch_channel_user(): resp = self.client.get(get_api_url('commands/facebook/get_channel_user', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) # FB_REQUESTS should not change on repeated calls self.assertFalse(FB_OBJECTS) self.assertTrue(len(FB_REQUESTS) == 1) self.assertEqual(FB_REQUESTS[0], (('/me',), {}))
def do_post(self, path, wrap_response=True, version=None, **kw): "Emulate POST request" path = get_api_url(path, version=self._get_version(version)) + '?token=%s' % self.auth_token base_url = kw.pop('base_url', 'https://localhost') data = json.dumps(kw) LOGGER.debug("Performing POST to %s with %s" % (path, data)) response = self.client.post(path, data=data, base_url=base_url, content_type='application/json') if wrap_response: return self._handle_http_response(response) else: return response
def test_like_unlike(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), object_id=self.fb_nativeid, ) data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/like', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_OBJECTS) == 1) self.assertTrue(len(FB_REQUESTS) == 0) self.assertEqual(FB_OBJECTS[0], ((u'facebook_post_id', 'likes'), {})) post_data['delete'] = True data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/like', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_OBJECTS) == 2) self.assertTrue(len(FB_REQUESTS) == 0) self.assertEqual(FB_OBJECTS[1], ((u'facebook_post_id', 'likes'), {'method': 'delete'})) self.efc.facebook_access_token = None self.efc.save() resp = self.client.get(get_api_url('commands/facebook/like', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 400) resp_data = json.loads(resp.data) self.assertFalse(resp_data['ok']) self.assertEqual(resp_data['code'], 364) self.assertTrue(len(FB_OBJECTS) == 2) self.assertTrue(len(FB_REQUESTS) == 0)
def test_follow_unfollow_user(self): # Create a user profile we can work with user_name = 'test_user' u_p = UserProfile.objects.upsert( 'Twitter', dict(user_name=user_name, user_id='12345678')) # First do a follow operation token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), user_profile=user_name) data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/follow_user', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue( len(LOGGED_ACTIONS) == 0) # In test mode we don't actually follow # The list of followers should be updated u_p.reload() self.assertEquals( u_p.followed_by_brands, [SocialProfile.make_id('Twitter', self.efc.twitter_handle_id)]) # Now do an unfollow post_data = dict(token=token, channel=str(self.channel.id), user_profile=user_name) data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/unfollow_user', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue( len(LOGGED_ACTIONS) == 0) # In test mode we don't actually follow # List should be empty again u_p.reload() self.assertTrue(u_p.followed_by_brands == [])
def test_share_post(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), post_url="this_is_post_url") data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/share', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_REQUESTS) == 1) self.assertEqual(FB_REQUESTS[0], (('/me/feed',), {'post_args': {'link': u'this_is_post_url'}}))
def test_auth_media_through_proxy(self, patched_connection_from_url, patched_proxy_manager_for): """Tests that requests.adapters.HTTPAdapter.get_connection chooses the correct connection to proxy for both http and https urls. """ proxied_media_urls = [ "http://pbs.twimg.com/media/made_up.jpg", "https://ton.twitter.com/1.1/ton/data/dm/5/5/made_up.png" ] ORIGINAL_PROXIES = app.config.get('PROXIES', {}) PROXIES = {'https': 'badproxytest'} app.config['PROXIES'] = PROXIES from solariat.utils.http_proxy import enable_proxy, disable_proxy disable_proxy() enable_proxy(settings=app.config) def raise_exception(error_message): class ExpectedTestException(Exception): pass def _effect(*args, **kwargs): raise ExpectedTestException(error_message) return _effect patched_connection_from_url.side_effect = raise_exception('no') patched_proxy_manager_for.side_effect = raise_exception('proxy') for media_url in proxied_media_urls: token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), media_url=media_url, data_uri=True) data = json.dumps(post_data) with self.assertRaises(Exception) as ctx: resp = self.client.get(get_api_url( 'commands/twitter/auth_media', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(str(ctx.exception), "proxy") patched_connection_from_url.assert_not_called() self.assertEqual(patched_proxy_manager_for.call_count, 1) self.assertEqual(patched_proxy_manager_for.call_args[0][0], 'http://' + PROXIES['https']) patched_proxy_manager_for.reset_mock() app.config['PROXIES'] = ORIGINAL_PROXIES
def test_create_favorite(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), object_id="test_status_id") data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/create_favorite', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 1) self.assertEqual(LOGGED_ACTIONS[0], ('create_favorite', (), { 'id': u'test_status_id' }))
def test_wall_post(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), target_id=self.fb_nativeid, message="test_message") data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/wall_post', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_OBJECTS) == 1) self.assertTrue(len(FB_REQUESTS) == 0) self.assertEqual(FB_OBJECTS[0], ('put_wall_post', ('test_message',), {'attachment': {}, 'profile_id': self.fb_nativeid}))
def test_conversation_recovery_throttled(self): from solariat.utils.timeslot import now, timedelta post_native_data, expected_conv_id = self.posts_native_data[2] fbs = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', posts_tracking_enabled=True) post = self._create_db_post(post_native_data['_wrapped_data']['message'], channel=fbs, facebook=post_native_data) conv_id = fbs.get_conversation_id(post) self.assertEqual(conv_id, expected_conv_id) conv = Conversation.objects.get() self.login(user=self.user) requests = mock.MagicMock() params = {'channel': str(fbs.id), 'limit': 10, 'reserve_time': 30, 'mode': 'conversation', 'token': self.auth_token} def assert_requests_get_called_once(): from solariat_bottle.settings import FBOT_URL, FB_DEFAULT_TOKEN url = FBOT_URL + '/json/restore-conversation?token=%s&conversation=%s' % (FB_DEFAULT_TOKEN, conv.id) requests.request.assert_called_once_with('get', url, verify=False, timeout=None) with mock.patch.dict('sys.modules', {'requests': requests}): response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') assert_requests_get_called_once() self.assertFalse(conv.mark_corrupted()) assert_requests_get_called_once() for update in [dict(unset__last_recovery_ts=True), dict(last_recovery_ts=None), dict(last_recovery_ts=now() - timedelta(hours=1))]: conv.update(**update) requests.request.reset_mock() self.assertTrue(conv.mark_corrupted()) assert_requests_get_called_once() self.assertFalse(conv.mark_corrupted()) assert_requests_get_called_once()
def test_basic(self): """ testing that endpoint basically works and returns correct number of utterances """ sample1 = "iPod headphones are so crap. Can anyone recommend me some good headphones?" token = self.get_token() data = {'samples': [sample1], 'token': token} self._create_classifier(token, "ClassifierOne", TYPE_CONTENT_BASIC) resp = self.client.post(get_api_url('analyzer/submit'), data=json.dumps(data), content_type='application/json', base_url='https://localhost') resp_data = json.loads(resp.data) self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp_data['list'][0]['utterances']), 2) self.assertTrue('latency' in resp_data)
def test_retweet_message(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), status_id="test_status_id", screen_name='test_user') data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/retweet_status', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 1) self.assertEqual(LOGGED_ACTIONS[0], ('retweet', (), { 'id': 'test_status_id' }))
def _fetch_channel_description(channel, expected_objects=()): del FB_REQUESTS[:] del FB_OBJECTS[:] token = self.get_token() post_data = dict(token=token, channel=str(channel.id)) data = json.dumps(post_data) resp = self.client.get( get_api_url('commands/facebook/get_channel_description', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertEqual(tuple([obj[0][0] for obj in FB_OBJECTS]), expected_objects) resp = json.loads(resp.data) self.assertTrue(resp['ok']) return resp['item']
def test_update_status(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), status="This is some test api status") data = json.dumps(post_data) resp = self.client.post(get_api_url('commands/twitter/update_status', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 1) self.assertEqual(LOGGED_ACTIONS[0], ('update_status', (), { 'status': u'This is some test api status', 'in_reply_to_status_id': None }))
def do_get(self, path, version=None, **kw): "Emulate GET request" kw['token'] = self.auth_token path = get_api_url(path, version=self._get_version(version=version)) if '?' in path: path += '&' else: path +='?' base_url = kw.pop('base_url', 'https://localhost') path += urllib.urlencode(kw) LOGGER.debug( "Performing GET with %s" % path) return self._handle_http_response( self.client.get(path, base_url=base_url))
def test_comment_post(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), object_id=self.fb_nativeid, message="test_message") data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/facebook/comment', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(FB_REQUESTS) == 1) self.assertEqual(FB_REQUESTS[0], (('facebook_post_id/comments',), {'post_args': {'message': 'test_message'}}))
def test_direct_message(self): token = self.get_token() post_data = dict(token=token, channel=str(self.channel.id), status="This is some test api status", screen_name='test_user') data = json.dumps(post_data) resp = self.client.get(get_api_url('commands/twitter/direct_message', version='v2.0'), data=data, content_type='application/json', base_url='https://localhost') self.assertEqual(resp.status_code, 200) self.assertTrue(len(LOGGED_ACTIONS) == 1) self.assertEqual(LOGGED_ACTIONS[0], ('send_direct_message', (), { 'screen_name': 'test_user', 'text': 'This is some test api status' }))
def test_add_missing_parents_on_pull__deleted_channel(self): root_post_data, _ = self.posts_native_data[0] post_data, _ = self.posts_native_data[1] fbs1 = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', posts_tracking_enabled=True) root_post = self._create_db_post(root_post_data['_wrapped_data']['message'], channel=fbs1, facebook=root_post_data) fbs1.archive() conv1 = Conversation.objects.get(posts=root_post.id) self.assertRaises(Channel.DoesNotExist, lambda: conv1.service_channel) fbs2 = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', posts_tracking_enabled=True) post = self._create_db_post(post_data['_wrapped_data']['message'], channel=fbs2, facebook=post_data) conv2 = Conversation.objects.get(posts=post.id) self.assertNotEqual(conv1.id, conv2.id) self.assertNotEqual(conv1.channels, conv2.channels) self.login(user=self.user) requests = mock.MagicMock() params = {'channel': str(fbs2.id), 'limit': 10, 'reserve_time': 30, 'mode': 'conversation', 'token': self.auth_token} from solariat.tests.base import LoggerInterceptor with mock.patch.dict('sys.modules', {'requests': requests}), LoggerInterceptor() as logs: response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') # root post was in database, # so it should be added without marking conversation as corrupted requests.get.assert_not_called() found_parent_msgs = [log.message for log in logs if 'Found parent post' in log.message] assert len(found_parent_msgs) == 1 conv2.reload() self.assertFalse(conv2.is_corrupted)
def test_basic(self): """ testing tagger endpoint using two simple samples """ sample1 = 'I need good headphones.' sample2 = 'Ipod headphones are so crappy.' sample1_tags = [[u'i', u'PRP'], [u'need', u'VBP'], [u'good', u'JJ'], [u'headphones', u'NNS'], [u'.', u'.']] sample2_tags = [[u'ipod', u'NN'], [u'headphones', u'NNS'], [u'are', u'VBP'], [u'so', u'RB'], [u'crappy', u'JJ'], [u'.', u'.']] token = self.get_token() data = {'samples': [sample1, sample2], 'token': token} resp = self.client.post(get_api_url('tagger/submit'), data=json.dumps(data), content_type='application/json', base_url='https://localhost') resp_data = json.loads(resp.data) self.assertEqual(resp.status_code, 200) self.assertEqual(resp_data["list"][0], sample1_tags) self.assertEqual(resp_data["list"][1], sample2_tags) self.assertTrue('latency' in resp_data)
def authenticate_api_user(params, token=None): debug_parameters = str(params) token = token or params.pop('token', None) if not token: raise api_exc.AuthorizationError("Auth token is not provided. Could not authenticate user. Params: " + str(debug_parameters), description="Any request will need a token.") user = AuthToken.objects.get_user(token) if not user: LOGGER.warning("Auth token %s is expired" % token) raise api_exc.AuthorizationError("Auth token %s is expired" % token) if get_var('ENFORCE_API_HTTPS') and not request.url.startswith('https://'): # Unsercure request, invalidate token LOGGER.warning("Received unsecure request from URL: " + str(request.url)) AuthToken.objects.remove(digest=token) description = "You have made an unsecured request over HTTP. Please use HTTPS for any subsequent calls. " description += "Your current token has automatically been removed. You can get a new one from the " description += "%s endpoint." % (get_var('HOST_DOMAIN') + get_api_url('authorize')).replace('http', 'https') raise api_exc.AuthorizationError(msg="Unsecure request done over HTTP. Your token has automatically removed.", description=description) return user
def run_fetch_queue_test(mode='conversation'): Conversation.objects.coll.remove() FacebookPost.objects.coll.remove() QueueMessage.objects.coll.remove() root_post = self._create_db_post(root_post_data['_wrapped_data']['message'], channel=fbs, facebook=root_post_data) conv = Conversation.objects.get() self.assertEqual([int(p) for p in conv.posts], [root_post.id]) QueueMessage.objects.coll.remove() # purge queue post = self._create_db_post(post_data['_wrapped_data']['message'], channel=fbs, facebook=post_data) self.login(user=self.user) requests = mock.MagicMock() params = {'channel': str(fbs.id), 'limit': 10, 'reserve_time': 30, 'mode': mode, 'token': self.auth_token} from solariat.tests.base import LoggerInterceptor with mock.patch.dict('sys.modules', {'requests': requests}), LoggerInterceptor() as logs: response = self.client.post( get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') data = json.loads(response.data) self.assertEqual(len(data['data']), 1) if 'post_ids' in data['data'][0]: self.assertEqual(data['data'][0]['post_ids'], [QueueMessage.objects.make_id(fbs.id, post.id)]) self.assertEqual(len(data['data'][0]['post_data']), 1) self.assertEqual(str(data['data'][0]['post_data'][0]['id']), str(post.id))
""" Specific endpoints for searching best matches and training for the task before hand. """ from flask import jsonify from solariat_bottle.app import app, get_api_url from solariat_bottle.utils.request import _get_request_data from solariat_bottle.db.matchable import Matchable, BenchmarkQuestion, BenchmarkTraining from solariat_bottle.db.post.utils import factory_by_user from solariat_bottle.tasks.commands import reset_channel_data from solariat_bottle.utils.decorators import login_required from solariat_bottle.settings import get_var @app.route(get_api_url('search', version='v1.2'), methods=['POST']) @login_required() def search_match(user): data = _get_request_data() BenchmarkQuestion.objects.create(received_data=data) # For internal book-keeping post_content = data['post_content'] channel_id = data['channel_id'] post = factory_by_user(user, content=post_content, channel=channel_id) return jsonify(ok=True, items=sorted([{'creative': _d['creative'], 'relevance': _d['relevance'], 'id': _d['id']} for _d in post._get_matchable_dicts()[0]], key=lambda x: -x['relevance'])) @app.route(get_api_url('clear_matches', version='v1.2'), methods=['POST']) @login_required()
def test_get_conversation_id(self): """test_get_conversation_id Facebook conversation ids for private messages may have different format Examples (thread_id is used as conversation id value): {"entry": [{"changes": [{"field": "conversations", "value": {"thread_id": "t_id.266468770144460", "page_id": 103645656349867}}], "id": "103645656349867", "time": 1467225704}], "object": "page"} {"entry": [{"changes": [{"field": "conversations", "value": {"thread_id": "t_mid.1467235818867:fb0791a508db32a096", "page_id": 297414983930888}}], "id": "297414983930888", "time": 1467235819}], "object": "page"} """ fbs = FacebookServiceChannel.objects.create_by_user(self.user, title='FBS', posts_tracking_enabled=True) expected_post_ids = [] for post_native_data, expected_conv_id in self.posts_native_data: post = self._create_db_post(post_native_data['_wrapped_data']['message'], channel=fbs, facebook=post_native_data) conv_id = fbs.get_conversation_id(post) self.assertEqual(conv_id, expected_conv_id) # check that conv id is derived from 'conversation_id' field self.assertTrue(str(conv_id) in post_native_data['conversation_id'], msg="{} not in {}".format(conv_id, post_native_data['conversation_id'])) expected_post_ids.append(post.id) self.assertEqual(Conversation.objects.count(), 2) conversation_posts = [] page_ids = ['167360800259', '297414983930888'] # page ids from test data for conversation in Conversation.objects(): self.assertIn(conversation.target_id, page_ids) conversation_posts.extend(conversation.posts) self.assertEqual(sorted(expected_post_ids), sorted(conversation_posts)) self.assertEqual(QueueMessage.objects.count(), 3) self.login(user=self.user) params = {'channel': str(fbs.id), 'limit': 10, 'reserve_time': 30, 'mode': 'conversation', 'token': self.auth_token} with mock.patch('solariat_bottle.db.conversation.Conversation.mark_corrupted', new_callable=mock.PropertyMock) as mark_corrupted: response = self.client.get(get_api_url('queue/fetch'), data=json.dumps(params), content_type='application/json', base_url='https://localhost') mark_corrupted.assert_called_once_with() data = json.loads(response.data) self.assertEqual(response.status_code, 200) self.assertEqual(data['ok'], True) # Only 3 posts, since we fetch in conversation mode self.assertEqual(len(data['data']), 1) # 1 conversation, another one is corrupted self.assertEqual(len(data['data'][0]['post_data']), 2) # 2 posts self.assertIsNotNone(data['metadata']) self.assertIsNotNone(data['metadata']['batch_token']) self.assertIsNotNone(data['metadata']['reserved_until']) post_ids = [] for entry in data['data']: post_ids.extend(entry['post_ids']) callback_params = {'token': self.auth_token, 'ids': post_ids} response = self.client.get(get_api_url('queue/confirm'), data=json.dumps(callback_params), content_type='application/json', base_url='https://localhost') data = json.loads(response.data) self.assertEqual(response.status_code, 200) self.assertTrue(data['ok']) self.assertEqual(len(Conversation.objects()), 2) self.assertEqual(len(QueueMessage.objects()), 1) # 1 post left from corrupted conversation