248 lines
7.8 KiB
Python
248 lines
7.8 KiB
Python
import pytest
|
|
import fbchat
|
|
import datetime
|
|
from fbchat._util import (
|
|
strip_json_cruft,
|
|
parse_json,
|
|
get_jsmods_require,
|
|
get_jsmods_define,
|
|
mimetype_to_key,
|
|
get_url_parameter,
|
|
seconds_to_datetime,
|
|
millis_to_datetime,
|
|
datetime_to_seconds,
|
|
datetime_to_millis,
|
|
seconds_to_timedelta,
|
|
millis_to_timedelta,
|
|
timedelta_to_seconds,
|
|
)
|
|
|
|
|
|
def test_strip_json_cruft():
|
|
assert strip_json_cruft('for(;;);{"abc": "def"}') == '{"abc": "def"}'
|
|
assert strip_json_cruft('{"abc": "def"}') == '{"abc": "def"}'
|
|
|
|
|
|
def test_strip_json_cruft_invalid():
|
|
with pytest.raises(AttributeError):
|
|
strip_json_cruft(None)
|
|
with pytest.raises(fbchat.ParseError, match="No JSON object found"):
|
|
strip_json_cruft("No JSON object here!")
|
|
|
|
|
|
def test_parse_json():
|
|
assert parse_json('{"a":"b"}') == {"a": "b"}
|
|
|
|
|
|
def test_parse_json_invalid():
|
|
with pytest.raises(fbchat.ParseError, match="Error while parsing JSON"):
|
|
parse_json("No JSON object here!")
|
|
|
|
|
|
def test_get_jsmods_require():
|
|
argument = {
|
|
"signalsToCollect": [
|
|
30000,
|
|
30001,
|
|
30003,
|
|
30004,
|
|
30005,
|
|
30002,
|
|
30007,
|
|
30008,
|
|
30009,
|
|
]
|
|
}
|
|
data = [
|
|
["BanzaiODS"],
|
|
[
|
|
"TuringClientSignalCollectionTrigger",
|
|
"startStaticSignalCollection",
|
|
[],
|
|
[argument],
|
|
],
|
|
]
|
|
assert get_jsmods_require(data) == {
|
|
"BanzaiODS": [],
|
|
"TuringClientSignalCollectionTrigger.startStaticSignalCollection": [argument],
|
|
}
|
|
|
|
|
|
def test_get_jsmods_require_version_specifier():
|
|
data = [
|
|
["DimensionTracking@1234"],
|
|
["CavalryLoggerImpl@2345", "startInstrumentation", [], []],
|
|
]
|
|
assert get_jsmods_require(data) == {
|
|
"DimensionTracking": [],
|
|
"CavalryLoggerImpl.startInstrumentation": [],
|
|
}
|
|
|
|
|
|
def test_get_jsmods_require_get_image_url():
|
|
data = [
|
|
[
|
|
"ServerRedirect",
|
|
"redirectPageTo",
|
|
[],
|
|
["https://scontent-arn2-1.xx.fbcdn.net/v/image.png&dl=1", False, False],
|
|
],
|
|
["TuringClientSignalCollectionTrigger", "...", [], [...]],
|
|
["TuringClientSignalCollectionTrigger", "retrieveSignals", [], [...]],
|
|
["BanzaiODS"],
|
|
["BanzaiScuba"],
|
|
]
|
|
url = "https://scontent-arn2-1.xx.fbcdn.net/v/image.png&dl=1"
|
|
assert get_jsmods_require(data)["ServerRedirect.redirectPageTo"][0] == url
|
|
|
|
|
|
def test_get_jsmods_define():
|
|
data = [
|
|
[
|
|
"BootloaderConfig",
|
|
[],
|
|
{
|
|
"jsRetries": [200, 500],
|
|
"jsRetryAbortNum": 2,
|
|
"jsRetryAbortTime": 5,
|
|
"payloadEndpointURI": "https://www.facebook.com/ajax/bootloader-endpoint/",
|
|
"preloadBE": False,
|
|
"assumeNotNonblocking": True,
|
|
"shouldCoalesceModuleRequestsMadeInSameTick": True,
|
|
"staggerJsDownloads": False,
|
|
"preloader_num_preloads": 0,
|
|
"preloader_preload_after_dd": False,
|
|
"preloader_num_loads": 1,
|
|
"preloader_enabled": False,
|
|
"retryQueuedBootloads": False,
|
|
"silentDups": False,
|
|
"asyncPreloadBoost": True,
|
|
},
|
|
123,
|
|
],
|
|
[
|
|
"CSSLoaderConfig",
|
|
[],
|
|
{"timeout": 5000, "modulePrefix": "BLCSS:", "loadEventSupported": True},
|
|
456,
|
|
],
|
|
["CurrentCommunityInitialData", [], {}, 789],
|
|
[
|
|
"CurrentEnvironment",
|
|
[],
|
|
{"facebookdotcom": True, "messengerdotcom": False},
|
|
987,
|
|
],
|
|
]
|
|
assert get_jsmods_define(data) == {
|
|
"BootloaderConfig": {
|
|
"jsRetries": [200, 500],
|
|
"jsRetryAbortNum": 2,
|
|
"jsRetryAbortTime": 5,
|
|
"payloadEndpointURI": "https://www.facebook.com/ajax/bootloader-endpoint/",
|
|
"preloadBE": False,
|
|
"assumeNotNonblocking": True,
|
|
"shouldCoalesceModuleRequestsMadeInSameTick": True,
|
|
"staggerJsDownloads": False,
|
|
"preloader_num_preloads": 0,
|
|
"preloader_preload_after_dd": False,
|
|
"preloader_num_loads": 1,
|
|
"preloader_enabled": False,
|
|
"retryQueuedBootloads": False,
|
|
"silentDups": False,
|
|
"asyncPreloadBoost": True,
|
|
},
|
|
"CSSLoaderConfig": {
|
|
"timeout": 5000,
|
|
"modulePrefix": "BLCSS:",
|
|
"loadEventSupported": True,
|
|
},
|
|
"CurrentCommunityInitialData": {},
|
|
"CurrentEnvironment": {"facebookdotcom": True, "messengerdotcom": False},
|
|
}
|
|
|
|
|
|
def test_get_jsmods_define_get_fb_dtsg():
|
|
data = [
|
|
["DTSGInitialData", [], {"token": "AQG-abcdefgh:AQGijklmnopq"}, 258],
|
|
[
|
|
"DTSGInitData",
|
|
[],
|
|
{"token": "AQG-abcdefgh:AQGijklmnopq", "async_get_token": "ABC123:DEF456"},
|
|
3515,
|
|
],
|
|
]
|
|
jsmods = get_jsmods_define(data)
|
|
assert (
|
|
jsmods["DTSGInitData"]["token"]
|
|
== jsmods["DTSGInitialData"]["token"]
|
|
== "AQG-abcdefgh:AQGijklmnopq"
|
|
)
|
|
|
|
|
|
def test_mimetype_to_key():
|
|
assert mimetype_to_key(None) == "file_id"
|
|
assert mimetype_to_key("image/gif") == "gif_id"
|
|
assert mimetype_to_key("video/mp4") == "video_id"
|
|
assert mimetype_to_key("video/quicktime") == "video_id"
|
|
assert mimetype_to_key("image/png") == "image_id"
|
|
assert mimetype_to_key("image/jpeg") == "image_id"
|
|
assert mimetype_to_key("audio/mpeg") == "audio_id"
|
|
assert mimetype_to_key("application/json") == "file_id"
|
|
|
|
|
|
def test_get_url_parameter():
|
|
assert get_url_parameter("http://example.com?a=b&c=d", "c") == "d"
|
|
assert get_url_parameter("http://example.com?a=b&a=c", "a") == "b"
|
|
assert get_url_parameter("http://example.com", "a") is None
|
|
|
|
|
|
DT_0 = datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
|
|
DT = datetime.datetime(2018, 11, 16, 1, 51, 4, 162000, tzinfo=datetime.timezone.utc)
|
|
DT_NO_TIMEZONE = datetime.datetime(2018, 11, 16, 1, 51, 4, 162000)
|
|
|
|
|
|
def test_seconds_to_datetime():
|
|
assert seconds_to_datetime(0) == DT_0
|
|
assert seconds_to_datetime(1542333064.162) == DT
|
|
assert seconds_to_datetime(1542333064.162) != DT_NO_TIMEZONE
|
|
|
|
|
|
def test_millis_to_datetime():
|
|
assert millis_to_datetime(0) == DT_0
|
|
assert millis_to_datetime(1542333064162) == DT
|
|
assert millis_to_datetime(1542333064162) != DT_NO_TIMEZONE
|
|
|
|
|
|
def test_datetime_to_seconds():
|
|
assert datetime_to_seconds(DT_0) == 0
|
|
assert datetime_to_seconds(DT) == 1542333064 # Rounded
|
|
datetime_to_seconds(DT_NO_TIMEZONE) # Depends on system timezone
|
|
|
|
|
|
def test_datetime_to_millis():
|
|
assert datetime_to_millis(DT_0) == 0
|
|
assert datetime_to_millis(DT) == 1542333064162
|
|
datetime_to_millis(DT_NO_TIMEZONE) # Depends on system timezone
|
|
|
|
|
|
def test_seconds_to_timedelta():
|
|
assert seconds_to_timedelta(0.001) == datetime.timedelta(microseconds=1000)
|
|
assert seconds_to_timedelta(1) == datetime.timedelta(seconds=1)
|
|
assert seconds_to_timedelta(3600) == datetime.timedelta(hours=1)
|
|
assert seconds_to_timedelta(86400) == datetime.timedelta(days=1)
|
|
|
|
|
|
def test_millis_to_timedelta():
|
|
assert millis_to_timedelta(1) == datetime.timedelta(microseconds=1000)
|
|
assert millis_to_timedelta(1000) == datetime.timedelta(seconds=1)
|
|
assert millis_to_timedelta(3600000) == datetime.timedelta(hours=1)
|
|
assert millis_to_timedelta(86400000) == datetime.timedelta(days=1)
|
|
|
|
|
|
def test_timedelta_to_seconds():
|
|
assert timedelta_to_seconds(datetime.timedelta(microseconds=1000)) == 0 # Rounded
|
|
assert timedelta_to_seconds(datetime.timedelta(seconds=1)) == 1
|
|
assert timedelta_to_seconds(datetime.timedelta(hours=1)) == 3600
|
|
assert timedelta_to_seconds(datetime.timedelta(days=1)) == 86400
|