handle null extra heartbeats
This commit is contained in:
		
							parent
							
								
									28cb3e2b28
								
							
						
					
					
						commit
						40c8a53019
					
				
					 5 changed files with 215 additions and 56 deletions
				
			
		| 
						 | 
				
			
			@ -809,6 +809,126 @@ class ArgumentsTestCase(TestCase):
 | 
			
		|||
                self.assertOfflineHeartbeatsSynced()
 | 
			
		||||
                self.assertSessionCacheSaved()
 | 
			
		||||
 | 
			
		||||
    @log_capture()
 | 
			
		||||
    def test_extra_heartbeats_with_null_heartbeat(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        response = CustomResponse()
 | 
			
		||||
        response.response_text = '[[{"id":1},201], [{"id":1},201]]'
 | 
			
		||||
        self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
        now1 = u(int(time.time()))
 | 
			
		||||
        project1 = os.path.basename(os.path.abspath('.'))
 | 
			
		||||
        project_not_used = 'xyz'
 | 
			
		||||
        entity1 = os.path.abspath('tests/samples/codefiles/emptyfile.txt')
 | 
			
		||||
        entity2 = os.path.abspath('tests/samples/codefiles/twolinefile.txt')
 | 
			
		||||
        config = 'tests/samples/configs/good_config.cfg'
 | 
			
		||||
        args = ['--time', now1, '--file', entity1, '--config', config, '--extra-heartbeats']
 | 
			
		||||
 | 
			
		||||
        with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
            now2 = int(time.time())
 | 
			
		||||
            heartbeats = json.dumps([
 | 
			
		||||
                None,
 | 
			
		||||
                {
 | 
			
		||||
                    'timestamp': now2,
 | 
			
		||||
                    'entity': entity2,
 | 
			
		||||
                    'entity_type': 'file',
 | 
			
		||||
                    'alternate_project': project_not_used,
 | 
			
		||||
                    'is_write': True,
 | 
			
		||||
                },
 | 
			
		||||
            ])
 | 
			
		||||
            mock_stdin.readline.return_value = heartbeats
 | 
			
		||||
 | 
			
		||||
            retval = execute(args)
 | 
			
		||||
 | 
			
		||||
            self.assertEquals(retval, SUCCESS)
 | 
			
		||||
            self.assertNothingPrinted()
 | 
			
		||||
            self.assertNothingLogged(logs)
 | 
			
		||||
 | 
			
		||||
            heartbeat = {
 | 
			
		||||
                'language': 'Text only',
 | 
			
		||||
                'lines': 0,
 | 
			
		||||
                'entity': entity1,
 | 
			
		||||
                'project': project1,
 | 
			
		||||
                'branch': ANY,
 | 
			
		||||
                'time': float(now1),
 | 
			
		||||
                'is_write': False,
 | 
			
		||||
                'type': 'file',
 | 
			
		||||
                'dependencies': [],
 | 
			
		||||
                'user_agent': ANY,
 | 
			
		||||
            }
 | 
			
		||||
            extra_heartbeats = [{
 | 
			
		||||
                'language': 'Text only',
 | 
			
		||||
                'lines': 2,
 | 
			
		||||
                'entity': entity2,
 | 
			
		||||
                'project': ANY,
 | 
			
		||||
                'branch': ANY,
 | 
			
		||||
                'time': float(now2),
 | 
			
		||||
                'is_write': True,
 | 
			
		||||
                'type': 'file',
 | 
			
		||||
                'dependencies': [],
 | 
			
		||||
                'user_agent': ANY,
 | 
			
		||||
            }]
 | 
			
		||||
            self.assertHeartbeatSent(heartbeat, extra_heartbeats=extra_heartbeats)
 | 
			
		||||
 | 
			
		||||
            self.assertHeartbeatNotSavedOffline()
 | 
			
		||||
            self.assertOfflineHeartbeatsSynced()
 | 
			
		||||
            self.assertSessionCacheSaved()
 | 
			
		||||
 | 
			
		||||
    @log_capture()
 | 
			
		||||
    def test_extra_heartbeats_with_skipped_heartbeat(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        response = CustomResponse()
 | 
			
		||||
        response.response_text = '[[{"id":1},201], [{"id":1},201]]'
 | 
			
		||||
        self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
        now1 = u(int(time.time()))
 | 
			
		||||
        project_not_used = 'xyz'
 | 
			
		||||
        entity1 = os.path.abspath('tests/samples/codefiles/emptyfile.txt')
 | 
			
		||||
        entity2 = os.path.abspath('tests/samples/codefiles/twolinefile.txt')
 | 
			
		||||
        config = 'tests/samples/configs/good_config.cfg'
 | 
			
		||||
        args = ['--time', now1, '--file', entity1, '--config', config, '--extra-heartbeats', '--exclude', 'twoline']
 | 
			
		||||
 | 
			
		||||
        with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
            now2 = int(time.time())
 | 
			
		||||
            heartbeats = json.dumps([
 | 
			
		||||
                {
 | 
			
		||||
                    'timestamp': now2,
 | 
			
		||||
                    'entity': entity2,
 | 
			
		||||
                    'entity_type': 'file',
 | 
			
		||||
                    'alternate_project': project_not_used,
 | 
			
		||||
                    'is_write': True,
 | 
			
		||||
                },
 | 
			
		||||
            ])
 | 
			
		||||
            mock_stdin.readline.return_value = heartbeats
 | 
			
		||||
 | 
			
		||||
            retval = execute(args)
 | 
			
		||||
 | 
			
		||||
            self.assertEquals(retval, SUCCESS)
 | 
			
		||||
            self.assertNothingPrinted()
 | 
			
		||||
            actual = self.getLogOutput(logs)
 | 
			
		||||
            expected = 'WakaTime WARNING Results from api not matching heartbeats sent.'
 | 
			
		||||
            self.assertIn(expected, actual)
 | 
			
		||||
 | 
			
		||||
            heartbeat = {
 | 
			
		||||
                'language': 'Text only',
 | 
			
		||||
                'lines': 0,
 | 
			
		||||
                'entity': entity1,
 | 
			
		||||
                'project': ANY,
 | 
			
		||||
                'branch': ANY,
 | 
			
		||||
                'time': float(now1),
 | 
			
		||||
                'is_write': False,
 | 
			
		||||
                'type': 'file',
 | 
			
		||||
                'dependencies': [],
 | 
			
		||||
                'user_agent': ANY,
 | 
			
		||||
            }
 | 
			
		||||
            self.assertHeartbeatSent(heartbeat)
 | 
			
		||||
 | 
			
		||||
            self.assertHeartbeatNotSavedOffline()
 | 
			
		||||
            self.assertOfflineHeartbeatsSynced()
 | 
			
		||||
            self.assertSessionCacheSaved()
 | 
			
		||||
 | 
			
		||||
    @log_capture()
 | 
			
		||||
    def test_uses_wakatime_home_env_variable(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,11 +15,10 @@ from testfixtures import log_capture
 | 
			
		|||
from wakatime.compat import u
 | 
			
		||||
from wakatime.constants import API_ERROR, AUTH_ERROR, SUCCESS
 | 
			
		||||
from wakatime.packages.requests.models import Response
 | 
			
		||||
from . import utils
 | 
			
		||||
from .utils import ANY, json, CustomResponse
 | 
			
		||||
from .utils import mock, json, ANY, CustomResponse, NamedTemporaryFile, TemporaryDirectory, TestCase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OfflineQueueTestCase(utils.TestCase):
 | 
			
		||||
class OfflineQueueTestCase(TestCase):
 | 
			
		||||
    patch_these = [
 | 
			
		||||
        'wakatime.packages.requests.adapters.HTTPAdapter.send',
 | 
			
		||||
        'wakatime.session_cache.SessionCache.save',
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +28,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    ]
 | 
			
		||||
 | 
			
		||||
    def test_heartbeat_saved_from_error_response(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -49,8 +48,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
 | 
			
		||||
 | 
			
		||||
    def test_heartbeat_discarded_from_400_response(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +68,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertEquals(None, saved_heartbeat)
 | 
			
		||||
 | 
			
		||||
    def test_offline_heartbeat_sent_after_success_response(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -94,8 +93,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertEquals(None, saved_heartbeat)
 | 
			
		||||
 | 
			
		||||
    def test_all_offline_heartbeats_sent_after_success_response(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -170,8 +169,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_heartbeats_sent_not_saved_from_bulk_response(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                entities = [
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +180,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    'go.go',
 | 
			
		||||
                ]
 | 
			
		||||
 | 
			
		||||
                with utils.TemporaryDirectory() as tempdir:
 | 
			
		||||
                with TemporaryDirectory() as tempdir:
 | 
			
		||||
                    for entity in entities:
 | 
			
		||||
                        shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +193,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
 | 
			
		||||
                    self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
                    with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                    with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                        heartbeats = json.dumps([{
 | 
			
		||||
                            'timestamp': now,
 | 
			
		||||
                            'entity': os.path.join(tempdir, entity),
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +202,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                        } for entity in entities[1:]])
 | 
			
		||||
                        mock_stdin.readline.return_value = heartbeats
 | 
			
		||||
 | 
			
		||||
                        with utils.mock.patch('wakatime.offlinequeue.Queue.pop') as mock_pop:
 | 
			
		||||
                        with mock.patch('wakatime.offlinequeue.Queue.pop') as mock_pop:
 | 
			
		||||
                            mock_pop.return_value = None
 | 
			
		||||
 | 
			
		||||
                            retval = execute(args)
 | 
			
		||||
| 
						 | 
				
			
			@ -253,8 +252,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_offline_heartbeats_sent_after_partial_success_from_bulk_response(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                entities = [
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +263,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    'go.go',
 | 
			
		||||
                ]
 | 
			
		||||
 | 
			
		||||
                with utils.TemporaryDirectory() as tempdir:
 | 
			
		||||
                with TemporaryDirectory() as tempdir:
 | 
			
		||||
                    for entity in entities:
 | 
			
		||||
                        shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -277,7 +276,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    response.response_text = '[[{"id":1},201], [{"error":"error 2"},500], [{"id":3},201], [{"error":4},500]]'
 | 
			
		||||
                    self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
                    with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                    with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                        heartbeats = json.dumps([{
 | 
			
		||||
                            'timestamp': now,
 | 
			
		||||
                            'entity': os.path.join(tempdir, entity),
 | 
			
		||||
| 
						 | 
				
			
			@ -306,8 +305,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_leftover_heartbeats_saved_when_bulk_response_not_matching_length(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                entities = [
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +318,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    'php.php',
 | 
			
		||||
                ]
 | 
			
		||||
 | 
			
		||||
                with utils.TemporaryDirectory() as tempdir:
 | 
			
		||||
                with TemporaryDirectory() as tempdir:
 | 
			
		||||
                    for entity in entities:
 | 
			
		||||
                        shutil.copy(os.path.join('tests/samples/codefiles', entity), os.path.join(tempdir, entity))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -332,7 +331,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                    response.response_text = '[[{"id":1},201], [{"id":3},201]]'
 | 
			
		||||
                    self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
                    with utils.mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                    with mock.patch('wakatime.main.sys.stdin') as mock_stdin:
 | 
			
		||||
                        heartbeats = json.dumps([{
 | 
			
		||||
                            'timestamp': now,
 | 
			
		||||
                            'entity': os.path.join(tempdir, entity),
 | 
			
		||||
| 
						 | 
				
			
			@ -358,8 +357,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                        self.assertEquals(len(saved_heartbeats), 2)
 | 
			
		||||
 | 
			
		||||
    def test_auth_error_when_sending_offline_heartbeats(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -404,8 +403,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertEquals(len(saved_heartbeats), 2)
 | 
			
		||||
 | 
			
		||||
    def test_500_error_when_sending_offline_heartbeats(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -450,8 +449,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertEquals(len(saved_heartbeats), 2)
 | 
			
		||||
 | 
			
		||||
    def test_empty_project_can_be_saved(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -470,9 +469,9 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                self.assertNothingPrinted()
 | 
			
		||||
                self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
 | 
			
		||||
 | 
			
		||||
    def test_get_handles_connection_exception(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
    def test_get_handles_exception_on_connect(self):
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -486,7 +485,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                args = ['--file', entity, '--config', config, '--time', now]
 | 
			
		||||
                execute(args)
 | 
			
		||||
 | 
			
		||||
                with utils.mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
 | 
			
		||||
                with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
 | 
			
		||||
                    mock_connect.side_effect = sqlite3.Error('')
 | 
			
		||||
 | 
			
		||||
                    response.status_code = 201
 | 
			
		||||
| 
						 | 
				
			
			@ -500,9 +499,9 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                saved_heartbeat = queue.pop()
 | 
			
		||||
                self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
 | 
			
		||||
 | 
			
		||||
    def test_push_handles_connection_exception(self):
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
    def test_push_handles_exception_on_connect(self):
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
| 
						 | 
				
			
			@ -513,7 +512,7 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                entity = 'tests/samples/codefiles/twolinefile.txt'
 | 
			
		||||
                config = 'tests/samples/configs/good_config.cfg'
 | 
			
		||||
 | 
			
		||||
                with utils.mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
 | 
			
		||||
                with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
 | 
			
		||||
                    mock_connect.side_effect = sqlite3.Error('')
 | 
			
		||||
 | 
			
		||||
                    args = ['--file', entity, '--config', config, '--time', now]
 | 
			
		||||
| 
						 | 
				
			
			@ -526,6 +525,43 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
                saved_heartbeat = queue.pop()
 | 
			
		||||
                self.assertEquals(None, saved_heartbeat)
 | 
			
		||||
 | 
			
		||||
    @log_capture()
 | 
			
		||||
    def test_push_handles_exception_on_query(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
                response.status_code = 500
 | 
			
		||||
                self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
                now = u(int(time.time()))
 | 
			
		||||
                entity = 'tests/samples/codefiles/twolinefile.txt'
 | 
			
		||||
                config = 'tests/samples/configs/good_config.cfg'
 | 
			
		||||
 | 
			
		||||
                mock_exec = mock.MagicMock()
 | 
			
		||||
                mock_exec.execute.side_effect = sqlite3.Error('')
 | 
			
		||||
 | 
			
		||||
                mock_conn = mock.MagicMock()
 | 
			
		||||
                mock_conn.execute.side_effect = sqlite3.Error('')
 | 
			
		||||
 | 
			
		||||
                with mock.patch('wakatime.offlinequeue.Queue.connect') as mock_connect:
 | 
			
		||||
                    mock_connect.return_value = (mock_conn, mock_exec)
 | 
			
		||||
 | 
			
		||||
                    args = ['--file', entity, '--config', config, '--time', now]
 | 
			
		||||
                    execute(args)
 | 
			
		||||
 | 
			
		||||
                    response.status_code = 201
 | 
			
		||||
                    execute(args)
 | 
			
		||||
 | 
			
		||||
                queue = Queue(None, None)
 | 
			
		||||
                saved_heartbeat = queue.pop()
 | 
			
		||||
                self.assertEquals(None, saved_heartbeat)
 | 
			
		||||
 | 
			
		||||
                self.assertNothingPrinted()
 | 
			
		||||
 | 
			
		||||
    def test_uses_home_folder_by_default(self):
 | 
			
		||||
        queue = Queue(None, None)
 | 
			
		||||
        db_file = queue._get_db_file()
 | 
			
		||||
| 
						 | 
				
			
			@ -535,10 +571,10 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_uses_wakatime_home_env_variable(self):
 | 
			
		||||
        queue = Queue(None, None)
 | 
			
		||||
 | 
			
		||||
        with utils.TemporaryDirectory() as tempdir:
 | 
			
		||||
        with TemporaryDirectory() as tempdir:
 | 
			
		||||
            expected = os.path.realpath(os.path.join(tempdir, '.wakatime.db'))
 | 
			
		||||
 | 
			
		||||
            with utils.mock.patch('os.environ.get') as mock_env:
 | 
			
		||||
            with mock.patch('os.environ.get') as mock_env:
 | 
			
		||||
                mock_env.return_value = os.path.realpath(tempdir)
 | 
			
		||||
 | 
			
		||||
                actual = queue._get_db_file()
 | 
			
		||||
| 
						 | 
				
			
			@ -548,8 +584,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_heartbeat_saved_when_requests_raises_exception(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                exception_msg = u("Oops, requests raised an exception. This is a test.")
 | 
			
		||||
| 
						 | 
				
			
			@ -579,15 +615,15 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_nonascii_heartbeat_saved(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = Response()
 | 
			
		||||
                response.status_code = 500
 | 
			
		||||
                self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
 | 
			
		||||
 | 
			
		||||
                with utils.TemporaryDirectory() as tempdir:
 | 
			
		||||
                with TemporaryDirectory() as tempdir:
 | 
			
		||||
                    filename = list(filter(lambda x: x.endswith('.txt'), os.listdir(u('tests/samples/codefiles/unicode'))))[0]
 | 
			
		||||
                    entity = os.path.join('tests/samples/codefiles/unicode', filename)
 | 
			
		||||
                    shutil.copy(entity, os.path.join(tempdir, filename))
 | 
			
		||||
| 
						 | 
				
			
			@ -613,10 +649,10 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
 | 
			
		||||
                    args = ['--file', entity, '--key', key, '--config', config, '--time', now]
 | 
			
		||||
 | 
			
		||||
                    with utils.mock.patch('wakatime.stats.standardize_language') as mock_language:
 | 
			
		||||
                    with mock.patch('wakatime.stats.standardize_language') as mock_language:
 | 
			
		||||
                        mock_language.return_value = (language, None)
 | 
			
		||||
 | 
			
		||||
                        with utils.mock.patch('wakatime.heartbeat.get_project_info') as mock_project:
 | 
			
		||||
                        with mock.patch('wakatime.heartbeat.get_project_info') as mock_project:
 | 
			
		||||
                            mock_project.return_value = (project, branch)
 | 
			
		||||
 | 
			
		||||
                            execute(args)
 | 
			
		||||
| 
						 | 
				
			
			@ -637,8 +673,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_heartbeat_saved_when_bulk_result_json_decode_error(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = CustomResponse()
 | 
			
		||||
| 
						 | 
				
			
			@ -665,8 +701,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_heartbeat_saved_from_result_type_error(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = CustomResponse()
 | 
			
		||||
| 
						 | 
				
			
			@ -693,8 +729,8 @@ class OfflineQueueTestCase(utils.TestCase):
 | 
			
		|||
    def test_heartbeat_saved_from_result_index_error(self, logs):
 | 
			
		||||
        logging.disable(logging.NOTSET)
 | 
			
		||||
 | 
			
		||||
        with utils.NamedTemporaryFile() as fh:
 | 
			
		||||
            with utils.mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
        with NamedTemporaryFile() as fh:
 | 
			
		||||
            with mock.patch('wakatime.offlinequeue.Queue._get_db_file') as mock_db_file:
 | 
			
		||||
                mock_db_file.return_value = fh.name
 | 
			
		||||
 | 
			
		||||
                response = CustomResponse()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,5 +96,5 @@ except ImportError:  # pragma: nocover
 | 
			
		|||
 | 
			
		||||
try:
 | 
			
		||||
    from .packages import simplejson as json
 | 
			
		||||
except (ImportError, SyntaxError):
 | 
			
		||||
except (ImportError, SyntaxError):  # pragma: nocover
 | 
			
		||||
    import json
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ from .constants import CONFIG_FILE_PARSE_ERROR
 | 
			
		|||
 | 
			
		||||
try:
 | 
			
		||||
    import configparser
 | 
			
		||||
except ImportError:
 | 
			
		||||
except ImportError:  # pragma: nocover
 | 
			
		||||
    from .packages import configparser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,10 @@ class Heartbeat(object):
 | 
			
		|||
    user_agent = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, data, args, configs, _clone=None):
 | 
			
		||||
        if not data:
 | 
			
		||||
            self.skip = u('Skipping because heartbeat data is missing.')
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self.args = args
 | 
			
		||||
        self.configs = configs
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +95,6 @@ class Heartbeat(object):
 | 
			
		|||
        data = self.dict()
 | 
			
		||||
        data.update(attrs)
 | 
			
		||||
        heartbeat = Heartbeat(data, self.args, self.configs, _clone=True)
 | 
			
		||||
        heartbeat.skip = self.skip
 | 
			
		||||
        return heartbeat
 | 
			
		||||
 | 
			
		||||
    def sanitize(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue