PR_Tool / tests /test_tgstat_api.py
Dink0's picture
Add optional TGStat archive fallback and fractional K counters for ReportBridge
152ccef verified
Raw History Blame Contribute Delete
3.03 kB
import unittest
from unittest.mock import Mock, patch
from reports import normalize, render
from tgstat_api import archive_link, archived_post
import service
class TGStatTests(unittest.TestCase):
def test_archive_link_and_validation(self):
self.assertEqual(archive_link('memtc', '1553'), 'https://tgstat.ru/channel/@memtc/1553')
with self.assertRaises(ValueError):
archive_link('../secret', '1')
def test_missing_token_does_not_request_anything(self):
get = Mock()
with patch.dict('os.environ', {'TGSTAT_API_TOKEN': ''}):
self.assertIsNone(archived_post('memtc', '1553', 'Канал', get))
get.assert_not_called()
def test_exact_counter_and_post_identity(self):
response = Mock()
response.json.return_value = {'status': 'ok', 'response': {'views': 845, 'link': 't.me/memtc/1553', 'is_deleted': 1}}
get = Mock(return_value=response)
with patch.dict('os.environ', {'TGSTAT_API_TOKEN': 'test-only'}):
post = archived_post('memtc', '1553', 'Канал', get)
self.assertEqual(post['views'], 845)
self.assertIn('(TGStat)', post['title'])
self.assertFalse(get.call_args.kwargs['allow_redirects'])
for views in (None, '845', True, -1):
response.json.return_value['response']['views'] = views
self.assertIsNone(archived_post('memtc', '1553', 'Канал', get))
response.json.return_value['response'].update(views=845, link='t.me/other/1')
self.assertIsNone(archived_post('memtc', '1553', 'Канал', get))
def test_fallback_only_after_telegram_failure_and_preserves_original_job_key(self):
record = normalize('https://t.me/memtc/1553')
fallback = dict(title='memtc (TGStat)', views=845, display_url=archive_link('memtc', '1553'), source='tgstat')
with patch.object(service.engine, 'process_telegram_link', return_value=('Ошибка', 0)), patch.object(service, 'archived_post', return_value=fallback):
result = service.fetch_one(record)
self.assertEqual(result['url'], record['url'])
self.assertIsNone(result['error'])
output = render([result])
self.assertIn('href="https://tgstat.ru/channel/@memtc/1553"', output['html'])
self.assertIn('0,8K', output['html'])
with patch.object(service.engine, 'process_telegram_link', return_value=('Канал', 845)), patch.object(service, 'archived_post') as archive:
service.fetch_one(record)
archive.assert_not_called()
def test_archive_api_failure_keeps_unknown_views_with_archive_link(self):
with patch.object(service.engine, 'process_telegram_link', side_effect=TimeoutError), patch.object(service, 'archived_post', side_effect=TimeoutError):
result = service.fetch_one(normalize('https://t.me/memtc/1553'))
self.assertIsNone(result['views'])
self.assertEqual(result['display_url'], archive_link('memtc', '1553'))