import os
import time
import unittest
from unittest.mock import Mock, patch
import legacy_parser as app
import max_api
URL = "https://max.ru/vkontakte/AaE-viFyB3E"
MID = "mid.ffffc217ccd5157d01a13ebe21720771"
PAGE = '''
'''
def page_response():
return Mock(status_code=200, text=PAGE)
class MaxPublicPostTests(unittest.TestCase):
def test_hydration_and_message_id(self):
title, channel_id = max_api.parse_public_post(PAGE, "vkontakte")
self.assertEqual(title, "Public & news")
self.assertEqual(channel_id, 68067500157571)
self.assertEqual(max_api.message_id_from_link(channel_id, "AaE-viFyB3E"), MID)
def test_missing_hydration_preserves_meta_title(self):
title, channel_id = max_api.parse_public_post(
'', "vkontakte",
)
self.assertEqual(title, "Public & news")
self.assertIsNone(channel_id)
def test_bad_post_id_is_rejected(self):
with self.assertRaises(ValueError):
max_api.message_id_from_link(68067500157571, "bad")
@patch.dict(os.environ, {"MAX_ACCESS_TOKEN": "test-token"})
def test_public_post_views_and_credentials(self):
session = Mock()
session.get.side_effect = [page_response(), Mock(status_code=200, json=lambda: {
"body": {"mid": MID}, "stat": {"views": 1197}, "url": URL,
})]
self.assertEqual(max_api.get_public_post(
session, "vkontakte", "AaE-viFyB3E", URL, (5, 8),
), ("Public & news", 1197))
public_request, api_request = session.get.call_args_list
self.assertNotIn("headers", public_request.kwargs)
self.assertEqual(api_request.args[0], max_api.API_BASE_URL + "/messages/" + MID)
self.assertEqual(api_request.kwargs["headers"], {"Authorization": "test-token"})
self.assertEqual(api_request.kwargs["verify"], max_api.CA_FILE)
self.assertFalse(api_request.kwargs["allow_redirects"])
@patch.dict(os.environ, {"MAX_ACCESS_TOKEN": "test-token"})
def test_denied_and_missing_counter_are_unknown_not_zero(self):
for response in [Mock(status_code=403), Mock(status_code=200, json=lambda: {
"body": {"mid": MID}, "stat": {},
}), Mock(status_code=200, json=lambda: {
"body": {"mid": "different"}, "stat": {"views": 9999},
})]:
with self.subTest(status=response.status_code):
session = Mock()
session.get.side_effect = [page_response(), response]
self.assertEqual(max_api.get_public_post(
session, "vkontakte", "AaE-viFyB3E", URL, (5, 8),
), ("Public & news", None))
@patch.dict(os.environ, {"MAX_ACCESS_TOKEN": "test-token"})
def test_real_zero_is_preserved(self):
session = Mock()
session.get.side_effect = [page_response(), Mock(status_code=200, json=lambda: {
"body": {"mid": MID}, "stat": {"views": 0},
})]
self.assertEqual(max_api.get_public_post(
session, "vkontakte", "AaE-viFyB3E", URL, (5, 8),
)[1], 0)
@patch.dict(os.environ, {"MAX_ACCESS_TOKEN": "test-token"})
def test_case_only_channel_difference_keeps_exact_message_check(self):
session = Mock()
session.get.side_effect = [page_response(), Mock(status_code=200, json=lambda: {
"body": {"mid": MID}, "stat": {"views": 1197},
"url": "https://max.ru/VKONTAKTE/AaE-viFyB3E/",
})]
self.assertEqual(max_api.get_public_post(session, "vkontakte", "AaE-viFyB3E", URL, (5, 8))[1], 1197)
def test_url_comparison_rejects_other_posts_and_hosts(self):
for url in ["https://max.ru/vkontakte/aaE-viFyB3E",
"https://max.ru/other/AaE-viFyB3E",
"https://evil.test/vkontakte/AaE-viFyB3E",
"https://user:pass@max.ru/vkontakte/AaE-viFyB3E",
"https://max.ru:8443/vkontakte/AaE-viFyB3E"]:
with self.subTest(url=url):
self.assertFalse(max_api.same_public_post_url(url, URL))
self.assertTrue(max_api.same_public_post_url("https://max.ru/Vkontakte/AaE-viFyB3E?from=share", URL))
def test_output_keeps_max_counters_and_partial_sum(self):
lines = [("max", URL, "vkontakte", "AaE-viFyB3E"),
("max", "https://max.ru/other/AaE-viFyB3E", "other", "AaE-viFyB3E")]
with patch.object(app, "resolve_max", return_value={
URL: ("Public & news", 1197), lines[1][1]: ("Other", None),
}):
html, text, _, _, errors, max_count = app.build_output(lines, time.monotonic() + 10)
self.assertIn("1,2K", html)
self.assertIn("Public & news", html)
self.assertIn("1,2K", text)
self.assertIn("Постов без данных о просмотрах: 1.", text)
self.assertEqual(len(errors), 1)
self.assertEqual(max_count, 2)
if __name__ == "__main__":
unittest.main()