Exemple #1
0
    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',), {}))
Exemple #7
0
    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])
Exemple #8
0
 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',), {}))
Exemple #10
0
    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)
Exemple #12
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'}}))
Exemple #14
0
    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
Exemple #15
0
 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}))
Exemple #17
0
    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)
Exemple #19
0
 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']
Exemple #21
0
 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
     }))
Exemple #22
0
    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'}}))
Exemple #24
0
 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'
                      }))
Exemple #25
0
    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)
Exemple #26
0
 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)
Exemple #27
0
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
Exemple #28
0
        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))
Exemple #29
0
"""
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()
Exemple #30
0
    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