Refactor models file structure

This commit is contained in:
Mads Marquart
2020-01-23 14:22:36 +01:00
parent 2aea401c79
commit a1fc235327
28 changed files with 116 additions and 119 deletions

View File

@@ -0,0 +1,459 @@
import pytest
import datetime
import fbchat
from fbchat import UnsentMessage, ShareAttachment
from fbchat._models._message import graphql_to_extensible_attachment
def test_parse_unsent_message():
data = {
"legacy_attachment_id": "ee.mid.$xyz",
"story_attachment": {
"description": {"text": "You removed a message"},
"media": None,
"source": None,
"style_list": ["globally_deleted_message_placeholder", "fallback"],
"title_with_entities": {"text": ""},
"properties": [],
"url": None,
"deduplication_key": "deadbeef123",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": None,
"subattachments": [],
},
"genie_attachment": {"genie_message": None},
}
assert UnsentMessage(id="ee.mid.$xyz") == graphql_to_extensible_attachment(data)
def test_share_from_graphql_minimal():
data = {
"target": {},
"url": "a.com",
"title_with_entities": {"text": "a.com"},
"subattachments": [],
}
assert ShareAttachment(
url="a.com", original_url="a.com", title="a.com"
) == ShareAttachment._from_graphql(data)
def test_share_from_graphql_link():
data = {
"description": {"text": ""},
"media": {
"animated_image": None,
"image": None,
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": {"text": "a.com"},
"style_list": ["share", "fallback"],
"title_with_entities": {"text": "a.com"},
"properties": [],
"url": "http://l.facebook.com/l.php?u=http%3A%2F%2Fa.com%2F&h=def&s=1",
"deduplication_key": "ee.mid.$xyz",
"action_links": [{"title": "About this website", "url": None}],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "ExternalUrl"},
"subattachments": [],
}
assert ShareAttachment(
author=None,
url="http://l.facebook.com/l.php?u=http%3A%2F%2Fa.com%2F&h=def&s=1",
original_url="http://a.com/",
title="a.com",
description="",
source="a.com",
image=None,
original_image_url=None,
attachments=[],
id="ee.mid.$xyz",
) == ShareAttachment._from_graphql(data)
def test_share_from_graphql_link_with_image():
data = {
"description": {
"text": (
"Create an account or log in to Facebook."
" Connect with friends, family and other people you know."
" Share photos and videos, send messages and get updates."
)
},
"media": {
"animated_image": None,
"image": {
"uri": "https://www.facebook.com/rsrc.php/v3/x.png",
"height": 325,
"width": 325,
},
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": None,
"style_list": ["share", "fallback"],
"title_with_entities": {"text": "Facebook log in or sign up"},
"properties": [],
"url": "http://facebook.com/",
"deduplication_key": "deadbeef123",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "ExternalUrl"},
"subattachments": [],
}
assert ShareAttachment(
author=None,
url="http://facebook.com/",
original_url="http://facebook.com/",
title="Facebook log in or sign up",
description=(
"Create an account or log in to Facebook."
" Connect with friends, family and other people you know."
" Share photos and videos, send messages and get updates."
),
source=None,
image=fbchat.Image(
url="https://www.facebook.com/rsrc.php/v3/x.png", width=325, height=325
),
original_image_url="https://www.facebook.com/rsrc.php/v3/x.png",
attachments=[],
id="deadbeef123",
) == ShareAttachment._from_graphql(data)
def test_share_from_graphql_video():
data = {
"description": {
"text": (
"Rick Astley's official music video for “Never Gonna Give You Up”"
" Listen to Rick Astley: https://RickAstley.lnk.to/_listenYD"
" Subscribe to the official Rick As..."
)
},
"media": {
"animated_image": None,
"image": {
"uri": (
"https://external-arn2-1.xx.fbcdn.net/safe_image.php?d=xyz123"
"&w=960&h=540&url=https%3A%2F%2Fi.ytimg.com%2Fvi%2FdQw4w9WgXcQ"
"%2Fmaxresdefault.jpg&sx=0&sy=0&sw=1280&sh=720&_nc_hash=abc123"
),
"height": 540,
"width": 960,
},
"playable_duration_in_ms": 0,
"is_playable": True,
"playable_url": "https://www.youtube.com/embed/dQw4w9WgXcQ?autoplay=1",
},
"source": {"text": "youtube.com"},
"style_list": ["share", "fallback"],
"title_with_entities": {
"text": "Rick Astley - Never Gonna Give You Up (Video)"
},
"properties": [
{"key": "width", "value": {"text": "1280"}},
{"key": "height", "value": {"text": "720"}},
],
"url": "https://l.facebook.com/l.php?u=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ",
"deduplication_key": "ee.mid.$gAAT4Sw1WSGhzQ9uRWVtEpZHZ8ZPV",
"action_links": [{"title": "About this website", "url": None}],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "ExternalUrl"},
"subattachments": [],
}
assert ShareAttachment(
author=None,
url="https://l.facebook.com/l.php?u=https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ",
original_url="https://youtu.be/dQw4w9WgXcQ",
title="Rick Astley - Never Gonna Give You Up (Video)",
description=(
"Rick Astley's official music video for “Never Gonna Give You Up”"
" Listen to Rick Astley: https://RickAstley.lnk.to/_listenYD"
" Subscribe to the official Rick As..."
),
source="youtube.com",
image=fbchat.Image(
url="https://external-arn2-1.xx.fbcdn.net/safe_image.php?d=xyz123"
"&w=960&h=540&url=https%3A%2F%2Fi.ytimg.com%2Fvi%2FdQw4w9WgXcQ"
"%2Fmaxresdefault.jpg&sx=0&sy=0&sw=1280&sh=720&_nc_hash=abc123",
width=960,
height=540,
),
original_image_url="https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
attachments=[],
id="ee.mid.$gAAT4Sw1WSGhzQ9uRWVtEpZHZ8ZPV",
) == ShareAttachment._from_graphql(data)
def test_share_with_image_subattachment():
data = {
"description": {"text": "Abc"},
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
"height": 960,
"width": 720,
},
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": {"text": "Def"},
"style_list": ["attached_story", "fallback"],
"title_with_entities": {"text": ""},
"properties": [],
"url": "https://www.facebook.com/groups/11223344/permalink/1234/",
"deduplication_key": "deadbeef123",
"action_links": [
{"title": None, "url": None},
{"title": None, "url": "https://www.facebook.com/groups/11223344/"},
{
"title": "Report Post to Admin",
"url": "https://www.facebook.com/groups/11223344/members/",
},
],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {
"__typename": "Story",
"title": None,
"description": {"text": "Abc"},
"actors": [
{
"__typename": "User",
"name": "Def",
"id": "1111",
"short_name": "Def",
"url": "https://www.facebook.com/some-user",
"profile_picture": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-1/c123.123.123.123a/s50x50/img.jpg",
"height": 50,
"width": 50,
},
}
],
"to": {
"__typename": "Group",
"name": "Some group",
"url": "https://www.facebook.com/groups/11223344/",
},
"attachments": [
{
"url": "https://www.facebook.com/photo.php?fbid=4321&set=gm.1234&type=3",
"media": {
"is_playable": False,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
"height": 960,
"width": 720,
},
},
}
],
"attached_story": None,
},
"subattachments": [
{
"description": {"text": "Abc"},
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
"height": 960,
"width": 720,
},
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": None,
"style_list": ["photo", "games_app", "fallback"],
"title_with_entities": {"text": ""},
"properties": [
{"key": "photoset_reference_token", "value": {"text": "gm.1234"}},
{"key": "layout_x", "value": {"text": "0"}},
{"key": "layout_y", "value": {"text": "0"}},
{"key": "layout_w", "value": {"text": "0"}},
{"key": "layout_h", "value": {"text": "0"}},
],
"url": "https://www.facebook.com/photo.php?fbid=4321&set=gm.1234&type=3",
"deduplication_key": "deadbeef456",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "Photo"},
}
],
}
assert ShareAttachment(
author="1111",
url="https://www.facebook.com/groups/11223344/permalink/1234/",
original_url="https://www.facebook.com/groups/11223344/permalink/1234/",
title="",
description="Abc",
source="Def",
image=fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
width=720,
height=960,
),
original_image_url="https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
attachments=[None],
id="deadbeef123",
) == ShareAttachment._from_graphql(data)
def test_share_with_video_subattachment():
data = {
"description": {"text": "Abc"},
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
"height": 540,
"width": 960,
},
"playable_duration_in_ms": 24469,
"is_playable": True,
"playable_url": "https://video-arn2-1.xx.fbcdn.net/v/t42.9040-2/vid.mp4",
},
"source": {"text": "Def"},
"style_list": ["attached_story", "fallback"],
"title_with_entities": {"text": ""},
"properties": [],
"url": "https://www.facebook.com/groups/11223344/permalink/1234/",
"deduplication_key": "deadbeef123",
"action_links": [
{"title": None, "url": None},
{"title": None, "url": "https://www.facebook.com/groups/11223344/"},
{"title": None, "url": None},
{"title": "A watch party is currently playing this video.", "url": None},
],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {
"__typename": "Story",
"title": None,
"description": {"text": "Abc"},
"actors": [
{
"__typename": "User",
"name": "Def",
"id": "1111",
"short_name": "Def",
"url": "https://www.facebook.com/some-user",
"profile_picture": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-1/c1.0.50.50a/p50x50/profile.jpg",
"height": 50,
"width": 50,
},
}
],
"to": {
"__typename": "Group",
"name": "Some group",
"url": "https://www.facebook.com/groups/11223344/",
},
"attachments": [
{
"url": "https://www.facebook.com/some-user/videos/2222/",
"media": {
"is_playable": True,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
"height": 540,
"width": 960,
},
},
}
],
"attached_story": None,
},
"subattachments": [
{
"description": None,
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
"height": 540,
"width": 960,
},
"playable_duration_in_ms": 24469,
"is_playable": True,
"playable_url": "https://video-arn2-1.xx.fbcdn.net/v/t42.9040-2/vid.mp4",
},
"source": None,
"style_list": [
"video_autoplay",
"video_inline",
"video",
"games_app",
"fallback",
],
"title_with_entities": {"text": ""},
"properties": [
{
"key": "can_autoplay_result",
"value": {"text": "ugc_default_allowed"},
}
],
"url": "https://www.facebook.com/some-user/videos/2222/",
"deduplication_key": "deadbeef456",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {
"__typename": "Video",
"video_id": "2222",
"video_messenger_cta_payload": None,
},
}
],
}
assert ShareAttachment(
author="1111",
url="https://www.facebook.com/groups/11223344/permalink/1234/",
original_url="https://www.facebook.com/groups/11223344/permalink/1234/",
title="",
description="Abc",
source="Def",
image=fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
width=960,
height=540,
),
original_image_url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
attachments=[
fbchat.VideoAttachment(
id="2222",
duration=datetime.timedelta(seconds=24, microseconds=469000),
preview_url="https://video-arn2-1.xx.fbcdn.net/v/t42.9040-2/vid.mp4",
previews={
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
width=960,
height=540,
)
},
)
],
id="deadbeef123",
) == ShareAttachment._from_graphql(data)

354
tests/models/test_file.py Normal file
View File

@@ -0,0 +1,354 @@
import datetime
import fbchat
from fbchat import FileAttachment, AudioAttachment, ImageAttachment, VideoAttachment
from fbchat._models._file import graphql_to_attachment, graphql_to_subattachment
def test_imageattachment_from_list():
data = {
"__typename": "MessageImage",
"id": "bWVzc2...",
"legacy_attachment_id": "1234",
"image": {"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/s261x260/1.jpg"},
"image1": {
"height": 463,
"width": 960,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/2.jpg",
},
"image2": {
"height": 988,
"width": 2048,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/s2048x2048/3.jpg",
},
"original_dimensions": {"x": 2833, "y": 1367},
"photo_encodings": [],
}
assert ImageAttachment(
id="1234",
width=2833,
height=1367,
previews={
fbchat.Image(url="https://scontent-arn2-1.xx.fbcdn.net/v/s261x260/1.jpg"),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/2.jpg",
width=960,
height=463,
),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/s2048x2048/3.jpg",
width=2048,
height=988,
),
},
) == ImageAttachment._from_list(data)
def test_videoattachment_from_list():
data = {
"__typename": "MessageVideo",
"id": "bWVzc2...",
"legacy_attachment_id": "1234",
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/p261x260/1.jpg"
},
"image1": {
"height": 368,
"width": 640,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/2.jpg",
},
"image2": {
"height": 368,
"width": 640,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/3.jpg",
},
"original_dimensions": {"x": 640, "y": 368},
}
assert VideoAttachment(
id="1234",
width=640,
height=368,
previews={
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/p261x260/1.jpg"
),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/2.jpg",
width=640,
height=368,
),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.3394-10/3.jpg",
width=640,
height=368,
),
},
) == VideoAttachment._from_list(data)
def test_graphql_to_attachment_empty():
assert fbchat.Attachment() == graphql_to_attachment({"__typename": "Unknown"})
def test_graphql_to_attachment_simple():
data = {"__typename": "Unknown", "legacy_attachment_id": "1234"}
assert fbchat.Attachment(id="1234") == graphql_to_attachment(data)
def test_graphql_to_attachment_file():
data = {
"__typename": "MessageFile",
"attribution_app": None,
"attribution_metadata": None,
"filename": "file.txt",
"url": "https://l.facebook.com/l.php?u=https%3A%2F%2Fcdn.fbsbx.com%2Fv%2Ffile.txt&h=AT1...&s=1",
"content_type": "attach:text",
"is_malicious": False,
"message_file_fbid": "1234",
"url_shimhash": "AT0...",
"url_skipshim": True,
}
assert FileAttachment(
id="1234",
url="https://l.facebook.com/l.php?u=https%3A%2F%2Fcdn.fbsbx.com%2Fv%2Ffile.txt&h=AT1...&s=1",
size=None,
name="file.txt",
is_malicious=False,
) == graphql_to_attachment(data)
def test_graphql_to_attachment_audio():
data = {
"__typename": "MessageAudio",
"attribution_app": None,
"attribution_metadata": None,
"filename": "audio.mp3",
"playable_url": "https://cdn.fbsbx.com/v/audio.mp3?dl=1",
"playable_duration_in_ms": 27745,
"is_voicemail": False,
"audio_type": "FILE_ATTACHMENT",
"url_shimhash": "AT0...",
"url_skipshim": True,
}
assert AudioAttachment(
id=None,
filename="audio.mp3",
url="https://cdn.fbsbx.com/v/audio.mp3?dl=1",
duration=datetime.timedelta(seconds=27, microseconds=745000),
audio_type="FILE_ATTACHMENT",
) == graphql_to_attachment(data)
def test_graphql_to_attachment_image1():
data = {
"__typename": "MessageImage",
"attribution_app": None,
"attribution_metadata": None,
"filename": "image-1234",
"preview": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/1.png",
"height": 128,
"width": 128,
},
"large_preview": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/1.png",
"height": 128,
"width": 128,
},
"thumbnail": {"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/p50x50/2.png"},
"photo_encodings": [],
"legacy_attachment_id": "1234",
"original_dimensions": {"x": 128, "y": 128},
"original_extension": "png",
"render_as_sticker": False,
"blurred_image_uri": None,
}
assert ImageAttachment(
id="1234",
original_extension="png",
width=None,
height=None,
is_animated=False,
previews={
fbchat.Image(url="https://scontent-arn2-1.xx.fbcdn.net/v/p50x50/2.png"),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/1.png",
width=128,
height=128,
),
},
) == graphql_to_attachment(data)
def test_graphql_to_attachment_image2():
data = {
"__typename": "MessageAnimatedImage",
"attribution_app": None,
"attribution_metadata": None,
"filename": "gif-1234",
"animated_image": {
"uri": "https://cdn.fbsbx.com/v/1.gif",
"height": 128,
"width": 128,
},
"legacy_attachment_id": "1234",
"preview_image": {
"uri": "https://cdn.fbsbx.com/v/1.gif",
"height": 128,
"width": 128,
},
"original_dimensions": {"x": 128, "y": 128},
}
assert ImageAttachment(
id="1234",
original_extension="gif",
width=None,
height=None,
is_animated=True,
previews={
fbchat.Image(url="https://cdn.fbsbx.com/v/1.gif", width=128, height=128)
},
) == graphql_to_attachment(data)
def test_graphql_to_attachment_video():
data = {
"__typename": "MessageVideo",
"attribution_app": None,
"attribution_metadata": None,
"filename": "video-4321.mp4",
"playable_url": "https://video-arn2-1.xx.fbcdn.net/v/video-4321.mp4",
"chat_image": {
"height": 96,
"width": 168,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/s168x128/1.jpg",
},
"legacy_attachment_id": "1234",
"video_type": "FILE_ATTACHMENT",
"original_dimensions": {"x": 640, "y": 368},
"playable_duration_in_ms": 6000,
"large_image": {
"height": 368,
"width": 640,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/2.jpg",
},
"inbox_image": {
"height": 260,
"width": 452,
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/p261x260/3.jpg",
},
}
assert VideoAttachment(
id="1234",
width=None,
height=None,
duration=datetime.timedelta(seconds=6),
preview_url="https://video-arn2-1.xx.fbcdn.net/v/video-4321.mp4",
previews={
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/s168x128/1.jpg",
width=168,
height=96,
),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/p261x260/3.jpg",
width=452,
height=260,
),
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/2.jpg",
width=640,
height=368,
),
},
) == graphql_to_attachment(data)
def test_graphql_to_subattachment_empty():
assert None is graphql_to_subattachment({})
def test_graphql_to_subattachment_image():
data = {
"description": {"text": "Abc"},
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/1.jpg",
"height": 960,
"width": 720,
},
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": None,
"style_list": ["photo", "games_app", "fallback"],
"title_with_entities": {"text": ""},
"properties": [
{"key": "photoset_reference_token", "value": {"text": "gm.4321"}},
{"key": "layout_x", "value": {"text": "0"}},
{"key": "layout_y", "value": {"text": "0"}},
{"key": "layout_w", "value": {"text": "0"}},
{"key": "layout_h", "value": {"text": "0"}},
],
"url": "https://www.facebook.com/photo.php?fbid=1234&set=gm.4321&type=3",
"deduplication_key": "8334...",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "Photo"},
}
assert None is graphql_to_subattachment(data)
def test_graphql_to_subattachment_video():
data = {
"description": None,
"media": {
"animated_image": None,
"image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
"height": 540,
"width": 960,
},
"playable_duration_in_ms": 24469,
"is_playable": True,
"playable_url": "https://video-arn2-1.xx.fbcdn.net/v/t42.9040-2/vid.mp4",
},
"source": None,
"style_list": [
"video_autoplay",
"video_inline",
"video",
"games_app",
"fallback",
],
"title_with_entities": {"text": ""},
"properties": [
{"key": "can_autoplay_result", "value": {"text": "ugc_default_allowed"}}
],
"url": "https://www.facebook.com/some-username/videos/1234/",
"deduplication_key": "ddb7...",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {
"__typename": "Video",
"video_id": "1234",
"video_messenger_cta_payload": None,
},
}
assert VideoAttachment(
id="1234",
duration=datetime.timedelta(seconds=24, microseconds=469000),
preview_url="https://video-arn2-1.xx.fbcdn.net/v/t42.9040-2/vid.mp4",
previews={
fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/t15.5256-10/p180x540/1.jpg",
width=960,
height=540,
)
},
) == graphql_to_subattachment(data)

View File

@@ -0,0 +1,96 @@
import pytest
import datetime
import fbchat
from fbchat import LocationAttachment, LiveLocationAttachment
def test_location_attachment_from_graphql():
data = {
"description": {"text": ""},
"media": {
"animated_image": None,
"image": {
"uri": "https://external-arn2-1.xx.fbcdn.net/static_map.php?v=1020&osm_provider=2&size=545x280&zoom=15&markers=55.40000000%2C12.43220000&language=en",
"height": 280,
"width": 545,
},
"playable_duration_in_ms": 0,
"is_playable": False,
"playable_url": None,
},
"source": None,
"style_list": ["message_location", "fallback"],
"title_with_entities": {"text": "Your location"},
"properties": [
{"key": "width", "value": {"text": "545"}},
{"key": "height", "value": {"text": "280"}},
],
"url": "https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.bing.com%2Fmaps%2Fdefault.aspx%3Fv%3D2%26pc%3DFACEBK%26mid%3D8100%26where1%3D55.4%252C%2B12.4322%26FORM%3DFBKPL1%26mkt%3Den-GB&h=a&s=1",
"deduplication_key": "400828513928715",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"xma_layout_info": None,
"target": {"__typename": "MessageLocation"},
"subattachments": [],
}
assert LocationAttachment(
id=400828513928715,
latitude=55.4,
longitude=12.4322,
image=fbchat.Image(
url="https://external-arn2-1.xx.fbcdn.net/static_map.php?v=1020&osm_provider=2&size=545x280&zoom=15&markers=55.40000000%2C12.43220000&language=en",
width=545,
height=280,
),
url="https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.bing.com%2Fmaps%2Fdefault.aspx%3Fv%3D2%26pc%3DFACEBK%26mid%3D8100%26where1%3D55.4%252C%2B12.4322%26FORM%3DFBKPL1%26mkt%3Den-GB&h=a&s=1",
) == LocationAttachment._from_graphql(data)
@pytest.mark.skip(reason="need to gather test data")
def test_live_location_from_pull():
data = ...
assert LiveLocationAttachment(...) == LiveLocationAttachment._from_pull(data)
def test_live_location_from_graphql_expired():
data = {
"description": {"text": "Last update 4 Jan"},
"media": None,
"source": None,
"style_list": ["message_live_location", "fallback"],
"title_with_entities": {"text": "Location-sharing ended"},
"properties": [],
"url": "https://www.facebook.com/",
"deduplication_key": "2254535444791641",
"action_links": [],
"messaging_attribution": None,
"messenger_call_to_actions": [],
"target": {
"__typename": "MessageLiveLocation",
"live_location_id": "2254535444791641",
"is_expired": True,
"expiration_time": 1546626345,
"sender": {"id": "100007056224713"},
"coordinate": None,
"location_title": None,
"sender_destination": None,
"stop_reason": "CANCELED",
},
"subattachments": [],
}
assert LiveLocationAttachment(
id=2254535444791641,
name="Location-sharing ended",
expires_at=datetime.datetime(
2019, 1, 4, 18, 25, 45, tzinfo=datetime.timezone.utc
),
is_expired=True,
url="https://www.facebook.com/",
) == LiveLocationAttachment._from_graphql(data)
@pytest.mark.skip(reason="need to gather test data")
def test_live_location_from_graphql():
data = ...
assert LiveLocationAttachment(...) == LiveLocationAttachment._from_graphql(data)

View File

@@ -0,0 +1,118 @@
import pytest
import fbchat
from fbchat import EmojiSize, Mention, Message, MessageData
from fbchat._models._message import graphql_to_extensible_attachment
@pytest.mark.parametrize(
"tags,size",
[
(None, None),
(["hot_emoji_size:unknown"], None),
(["bunch", "of:different", "tags:large", "hot_emoji_size:s"], EmojiSize.SMALL),
(["hot_emoji_size:s"], EmojiSize.SMALL),
(["hot_emoji_size:m"], EmojiSize.MEDIUM),
(["hot_emoji_size:l"], EmojiSize.LARGE),
(["hot_emoji_size:small"], EmojiSize.SMALL),
(["hot_emoji_size:medium"], EmojiSize.MEDIUM),
(["hot_emoji_size:large"], EmojiSize.LARGE),
],
)
def test_emojisize_from_tags(tags, size):
assert size is EmojiSize._from_tags(tags)
def test_graphql_to_extensible_attachment_empty():
assert None is graphql_to_extensible_attachment({})
@pytest.mark.parametrize(
"obj,type_",
[
# UnsentMessage testing is done in test_attachment.py
(fbchat.LocationAttachment, "MessageLocation"),
(fbchat.LiveLocationAttachment, "MessageLiveLocation"),
(fbchat.ShareAttachment, "ExternalUrl"),
(fbchat.ShareAttachment, "Story"),
],
)
def test_graphql_to_extensible_attachment_dispatch(monkeypatch, obj, type_):
monkeypatch.setattr(obj, "_from_graphql", lambda data: True)
data = {"story_attachment": {"target": {"__typename": type_}}}
assert graphql_to_extensible_attachment(data)
def test_mention_from_range():
data = {"length": 17, "offset": 0, "entity": {"__typename": "User", "id": "1234"}}
assert Mention(thread_id="1234", offset=0, length=17) == Mention._from_range(data)
data = {
"length": 2,
"offset": 10,
"entity": {"__typename": "MessengerViewer1To1Thread"},
}
assert Mention(thread_id=None, offset=10, length=2) == Mention._from_range(data)
data = {
"length": 5,
"offset": 21,
"entity": {"__typename": "MessengerViewerGroupThread"},
}
assert Mention(thread_id=None, offset=21, length=5) == Mention._from_range(data)
def test_mention_to_send_data():
assert {
"profile_xmd[0][id]": "1234",
"profile_xmd[0][length]": 7,
"profile_xmd[0][offset]": 4,
"profile_xmd[0][type]": "p",
} == Mention(thread_id="1234", offset=4, length=7)._to_send_data(0)
assert {
"profile_xmd[1][id]": "4321",
"profile_xmd[1][length]": 7,
"profile_xmd[1][offset]": 24,
"profile_xmd[1][type]": "p",
} == Mention(thread_id="4321", offset=24, length=7)._to_send_data(1)
def test_message_format_mentions():
expected = (
"Hey 'Peter'! My name is Michael",
[
Mention(thread_id="1234", offset=4, length=7),
Mention(thread_id="4321", offset=24, length=7),
],
)
assert expected == Message.format_mentions(
"Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")
)
assert expected == Message.format_mentions(
"Hey {p!r}! My name is {}", ("4321", "Michael"), p=("1234", "Peter")
)
def test_message_get_forwarded_from_tags():
assert not MessageData._get_forwarded_from_tags(None)
assert not MessageData._get_forwarded_from_tags(["hot_emoji_size:unknown"])
assert MessageData._get_forwarded_from_tags(
["attachment:photo", "inbox", "sent", "source:chat:forward", "tq"]
)
@pytest.mark.skip(reason="need to be added")
def test_message_to_send_data_quick_replies():
raise NotImplementedError
@pytest.mark.skip(reason="need to gather test data")
def test_message_from_graphql():
pass
@pytest.mark.skip(reason="need to gather test data")
def test_message_from_reply():
pass
@pytest.mark.skip(reason="need to gather test data")
def test_message_from_pull():
pass

155
tests/models/test_plan.py Normal file
View File

@@ -0,0 +1,155 @@
import datetime
from fbchat import GuestStatus, PlanData
def test_plan_properties(session):
plan = PlanData(
session=session,
id="1234567890",
time=...,
title=...,
guests={
"1234": GuestStatus.INVITED,
"2345": GuestStatus.INVITED,
"3456": GuestStatus.GOING,
"4567": GuestStatus.DECLINED,
},
)
assert set(plan.invited) == {"1234", "2345"}
assert plan.going == ["3456"]
assert plan.declined == ["4567"]
def test_plan_from_pull(session):
data = {
"event_timezone": "",
"event_creator_id": "1234",
"event_id": "1111",
"event_type": "EVENT",
"event_track_rsvp": "1",
"event_title": "abc",
"event_time": "1500000000",
"event_seconds_to_notify_before": "3600",
"guest_state_list": (
'[{"guest_list_state":"INVITED","node":{"id":"1234"}},'
'{"guest_list_state":"INVITED","node":{"id":"2356"}},'
'{"guest_list_state":"DECLINED","node":{"id":"3456"}},'
'{"guest_list_state":"GOING","node":{"id":"4567"}}]'
),
}
assert PlanData(
session=session,
id="1111",
time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
title="abc",
author_id="1234",
guests={
"1234": GuestStatus.INVITED,
"2356": GuestStatus.INVITED,
"3456": GuestStatus.DECLINED,
"4567": GuestStatus.GOING,
},
) == PlanData._from_pull(session, data)
def test_plan_from_fetch(session):
data = {
"message_thread_id": 123456789,
"event_time": 1500000000,
"creator_id": 1234,
"event_time_updated_time": 1450000000,
"title": "abc",
"track_rsvp": 1,
"event_type": "EVENT",
"status": "created",
"message_id": "mid.xyz",
"seconds_to_notify_before": 3600,
"event_time_source": "user",
"repeat_mode": "once",
"creation_time": 1400000000,
"location_id": 0,
"location_name": None,
"latitude": "",
"longitude": "",
"event_id": 0,
"trigger_message_id": "",
"note": "",
"timezone_id": 0,
"end_time": 0,
"list_id": 0,
"payload_id": 0,
"cu_app": "",
"location_sharing_subtype": "",
"reminder_notif_param": [],
"workplace_meeting_id": "",
"genie_fbid": 0,
"galaxy": "",
"oid": 1111,
"type": 8128,
"is_active": True,
"location_address": None,
"event_members": {
"1234": "INVITED",
"2356": "INVITED",
"3456": "DECLINED",
"4567": "GOING",
},
}
assert PlanData(
session=session,
id=1111,
time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
title="abc",
location="",
location_id="",
author_id=1234,
guests={
"1234": GuestStatus.INVITED,
"2356": GuestStatus.INVITED,
"3456": GuestStatus.DECLINED,
"4567": GuestStatus.GOING,
},
) == PlanData._from_fetch(session, data)
def test_plan_from_graphql(session):
data = {
"id": "1111",
"lightweight_event_creator": {"id": "1234"},
"time": 1500000000,
"lightweight_event_type": "EVENT",
"location_name": None,
"location_coordinates": None,
"location_page": None,
"lightweight_event_status": "CREATED",
"note": "",
"repeat_mode": "ONCE",
"event_title": "abc",
"trigger_message": None,
"seconds_to_notify_before": 3600,
"allows_rsvp": True,
"related_event": None,
"event_reminder_members": {
"edges": [
{"node": {"id": "1234"}, "guest_list_state": "INVITED"},
{"node": {"id": "2356"}, "guest_list_state": "INVITED"},
{"node": {"id": "3456"}, "guest_list_state": "DECLINED"},
{"node": {"id": "4567"}, "guest_list_state": "GOING"},
]
},
}
assert PlanData(
session=session,
time=datetime.datetime(2017, 7, 14, 2, 40, tzinfo=datetime.timezone.utc),
title="abc",
location="",
location_id="",
id="1111",
author_id="1234",
guests={
"1234": GuestStatus.INVITED,
"2356": GuestStatus.INVITED,
"3456": GuestStatus.DECLINED,
"4567": GuestStatus.GOING,
},
) == PlanData._from_graphql(session, data)

94
tests/models/test_poll.py Normal file
View File

@@ -0,0 +1,94 @@
from fbchat import Poll, PollOption
def test_poll_option_from_graphql_unvoted():
data = {
"id": "123456789",
"text": "abc",
"total_count": 0,
"viewer_has_voted": "false",
"voters": [],
}
assert PollOption(
text="abc", vote=False, voters=[], votes_count=0, id="123456789"
) == PollOption._from_graphql(data)
def test_poll_option_from_graphql_voted():
data = {
"id": "123456789",
"text": "abc",
"total_count": 2,
"viewer_has_voted": "true",
"voters": ["1234", "2345"],
}
assert PollOption(
text="abc", vote=True, voters=["1234", "2345"], votes_count=2, id="123456789"
) == PollOption._from_graphql(data)
def test_poll_option_from_graphql_alternate_format():
# Format received when fetching poll options
data = {
"id": "123456789",
"text": "abc",
"viewer_has_voted": True,
"voters": {
"count": 2,
"edges": [{"node": {"id": "1234"}}, {"node": {"id": "2345"}}],
},
}
assert PollOption(
text="abc", vote=True, voters=["1234", "2345"], votes_count=2, id="123456789"
) == PollOption._from_graphql(data)
def test_poll_from_graphql(session):
data = {
"id": "123456789",
"text": "Some poll",
"total_count": 5,
"viewer_has_voted": "true",
"options": [
{
"id": "1111",
"text": "Abc",
"total_count": 1,
"viewer_has_voted": "true",
"voters": ["1234"],
},
{
"id": "2222",
"text": "Def",
"total_count": 2,
"viewer_has_voted": "false",
"voters": ["2345", "3456"],
},
{
"id": "3333",
"text": "Ghi",
"total_count": 0,
"viewer_has_voted": "false",
"voters": [],
},
],
}
assert Poll(
session=session,
question="Some poll",
options=[
PollOption(
text="Abc", vote=True, voters=["1234"], votes_count=1, id="1111"
),
PollOption(
text="Def",
vote=False,
voters=["2345", "3456"],
votes_count=2,
id="2222",
),
PollOption(text="Ghi", vote=False, voters=[], votes_count=0, id="3333"),
],
options_count=5,
id=123456789,
) == Poll._from_graphql(session, data)

View File

@@ -0,0 +1,49 @@
from fbchat import (
QuickReplyText,
QuickReplyLocation,
QuickReplyPhoneNumber,
QuickReplyEmail,
)
from fbchat._models._quick_reply import graphql_to_quick_reply
def test_parse_minimal():
data = {
"content_type": "text",
"payload": None,
"external_payload": None,
"data": None,
"title": "A",
"image_url": None,
}
assert QuickReplyText(title="A") == graphql_to_quick_reply(data)
data = {"content_type": "location"}
assert QuickReplyLocation() == graphql_to_quick_reply(data)
data = {"content_type": "user_phone_number"}
assert QuickReplyPhoneNumber() == graphql_to_quick_reply(data)
data = {"content_type": "user_email"}
assert QuickReplyEmail() == graphql_to_quick_reply(data)
def test_parse_text_full():
data = {
"content_type": "text",
"title": "A",
"payload": "Some payload",
"image_url": "https://example.com/image.jpg",
"data": None,
}
assert QuickReplyText(
payload="Some payload",
data=None,
is_response=False,
title="A",
image_url="https://example.com/image.jpg",
) == graphql_to_quick_reply(data)
def test_parse_with_is_response():
data = {"content_type": "text"}
assert QuickReplyText(is_response=True) == graphql_to_quick_reply(
data, is_response=True
)

View File

@@ -0,0 +1,91 @@
import pytest
import fbchat
from fbchat import Sticker
def test_from_graphql_none():
assert None == Sticker._from_graphql(None)
def test_from_graphql_minimal():
assert Sticker(id=1) == Sticker._from_graphql({"id": 1})
def test_from_graphql_normal():
assert Sticker(
id="369239383222810",
pack="227877430692340",
is_animated=False,
frames_per_row=1,
frames_per_col=1,
frame_count=1,
frame_rate=83,
image=fbchat.Image(
url="https://scontent-arn2-1.xx.fbcdn.net/v/redacted.png",
width=274,
height=274,
),
label="Like, thumbs up",
) == Sticker._from_graphql(
{
"id": "369239383222810",
"pack": {"id": "227877430692340"},
"label": "Like, thumbs up",
"frame_count": 1,
"frame_rate": 83,
"frames_per_row": 1,
"frames_per_column": 1,
"sprite_image_2x": None,
"sprite_image": None,
"padded_sprite_image": None,
"padded_sprite_image_2x": None,
"url": "https://scontent-arn2-1.xx.fbcdn.net/v/redacted.png",
"height": 274,
"width": 274,
}
)
def test_from_graphql_animated():
assert Sticker(
id="144885035685763",
pack="350357561732812",
is_animated=True,
medium_sprite_image="https://scontent-arn2-1.xx.fbcdn.net/v/redacted2.png",
large_sprite_image="https://scontent-arn2-1.fbcdn.net/v/redacted3.png",
frames_per_row=2,
frames_per_col=2,
frame_count=4,
frame_rate=142,
image=fbchat.Image(
url="https://scontent-arn2-1.fbcdn.net/v/redacted1.png",
width=240,
height=293,
),
label="Love, cat with heart",
) == Sticker._from_graphql(
{
"id": "144885035685763",
"pack": {"id": "350357561732812"},
"label": "Love, cat with heart",
"frame_count": 4,
"frame_rate": 142,
"frames_per_row": 2,
"frames_per_column": 2,
"sprite_image_2x": {
"uri": "https://scontent-arn2-1.fbcdn.net/v/redacted3.png"
},
"sprite_image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/redacted2.png"
},
"padded_sprite_image": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/unused1.png"
},
"padded_sprite_image_2x": {
"uri": "https://scontent-arn2-1.xx.fbcdn.net/v/unused2.png"
},
"url": "https://scontent-arn2-1.fbcdn.net/v/redacted1.png",
"height": 293,
"width": 240,
}
)