1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/social_linkedin/tests/test_social_linkedin.py
2024-12-10 09:04:09 +07:00

204 lines
8.2 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import requests
import json
from unittest.mock import patch
from odoo.addons.mail.tools import link_preview
from odoo.addons.social.tests.common import SocialCase
from odoo.addons.social.tests.tools import mock_void_external_calls
from odoo.addons.social_linkedin.models.social_live_post import SocialLivePostLinkedin
from odoo.addons.social_linkedin.models.social_account import SocialAccountLinkedin
from odoo.tools.misc import mute_logger
class SocialLinkedinCase(SocialCase):
@classmethod
def setUpClass(cls):
with mock_void_external_calls():
super(SocialLinkedinCase, cls).setUpClass()
cls.social_accounts.write({'linkedin_access_token': 'ABCD'})
def test_post_success(self):
self._test_post()
def test_post_failure(self):
self._test_post(False)
@mute_logger("odoo.addons.social.models.social_account")
def _test_post(self, success=True):
self.assertEqual(self.social_post.state, 'draft')
def _patched_post(*args, **kwargs):
response = requests.Response()
if success:
response._content = b'{"id": "42"}'
response.status_code = 200
response.headers = {'x-restli-id': 'fake_created_post_urn'}
else:
response._content = b'{"serviceErrorCode": 65600}'
response.status_code = 404
return response
with patch.object(requests, 'post', _patched_post), \
patch.object(SocialLivePostLinkedin, '_linkedin_upload_image', lambda *a, **kw: 'fake_image_urn'):
self.social_post._action_post()
self._checkPostedStatus(success)
if success:
linkedin_post_id = self.social_post.live_post_ids.mapped('linkedin_post_id')
self.assertEqual(linkedin_post_id, ['fake_created_post_urn'] * 2)
self.assertTrue(
all([not account.is_media_disconnected for account in self.social_post.account_ids]),
'Accounts should not be marked disconnected if post is successful')
else:
self.assertTrue(
all([account.is_media_disconnected for account in self.social_post.account_ids]),
'Accounts should be marked disconnected if post has failed')
def test_post_image(self):
"""
Check the priority of the ``post type``
The first priority is image
"""
self.social_post.message = 'A message https://example.com'
self.assertTrue(self.social_post.image_ids)
self._test_post_type('multiImage')
def test_post_urls(self):
"""
Check the priority of the ``post type``
The second priority is urls
"""
self.social_post.message = 'A message https://example.com'
self.social_post.image_ids = False
return self._test_post_type('article')
def test_post_urls_metadata(self):
"""Same as @test_post_urls, but this time the page has some metadata."""
def _patched_get_link_preview_from_url(*args, **kwargs):
return {
'og_image': 'https://example.com/thumbnail',
'og_mimetype': 'text/html',
'og_title': 'Super Article',
}
def _patched_get(url, *args, **kwargs):
response = requests.Response()
response.status_code = 200
if url == 'https://example.com/thumbnail':
response._content = base64.b64decode(b'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==')
response.headers['Content-Type'] = 'image/gif'
return response
with (patch.object(link_preview, 'get_link_preview_from_url', side_effect=_patched_get_link_preview_from_url),
patch.object(requests, 'get', side_effect=_patched_get)):
posts_values = self.test_post_urls()
self.assertEqual(posts_values[0].get('content', {}).get('article', {}).get('thumbnail', {}), 'fake_image_urn')
def test_post_text(self):
"""
Check the priority of the ``post type``
The last priority is text
"""
self.social_post.message = 'A message without URL'
self.social_post.image_ids = False
self._test_post_type(None)
def _test_post_type(self, expected_post_type):
self.assertEqual(self.social_post.state, 'draft')
def _patched_post(*args, **kwargs):
response = requests.Response()
response._content = b'{"id": "42"}'
response.status_code = 200
post_values = kwargs.get('json', {})
post_types = post_values.get('content', {}).keys()
posts_types.extend(post_types or [None])
posts_values.append(post_values)
return response
posts_types = []
posts_values = []
with patch.object(requests, 'post', _patched_post), \
patch.object(SocialLivePostLinkedin, '_linkedin_upload_image', lambda *a, **kw: 'fake_image_urn'):
self.social_post._action_post()
self.assertTrue(posts_types)
self.assertTrue(all(response == expected_post_type for response in posts_types),
'The post type must be [%s]' % expected_post_type)
return posts_values
@classmethod
def _get_social_media(cls):
return cls.env.ref('social_linkedin.social_media_linkedin')
def _get_commentary_after_post(self):
commentaries = []
def _patched_post(*args, **kwargs):
commentaries.append(kwargs.get('json', {}).get('commentary', None))
with patch.object(requests, 'post', _patched_post):
self.social_post._action_post()
return commentaries
def test_post_with_special_char(self):
"""
Check the priority of the ``post type``
The last priority is text
"""
self.social_post.message = '(This) <is> {a} [test] string <3'
self.social_post.image_ids = False
commentaries = self._get_commentary_after_post()
expected_output = '\\(This\\) \\<is\\> \\{a\\} \\[test\\] string \\<3'
self.assertTrue(all([commentary == expected_output for commentary in commentaries]))
def test_fetch_media_urns(self):
"""Test that all urns get a download url."""
def _patched_linkedin_request(endpoint, *args, **kwargs):
response = requests.Response()
response.status_code = 200
content = {}
if 'image' in endpoint:
content = {
'results': {
'urn:li:image:456': {'downloadUrl': 'https://example.com/456'},
'urn:li:image:789': {'downloadUrl': 'https://example.com/789'},
}
}
elif 'video' in endpoint:
content = {
'results': {
'urn:li:video:123': {'downloadUrl': 'https://example.com/123'},
}
}
response._content = json.dumps(content).encode()
return response
fake_post_data = [
# Video URN
{'content': {'media': {'id': 'urn:li:video:123'}}},
# Image URN
{'content': {'media': {'id': 'urn:li:image:456'}}},
# Multi Image URN
{'content': {'multiImage': {'images': [{'id': 'urn:li:image:789'}]}}},
]
with patch.object(type(self.env['social.account']), '_linkedin_request', side_effect=_patched_linkedin_request):
self.env['social.stream']._prepare_linkedin_stream_post_images(fake_post_data)
self.assertTrue(fake_post_data)
video_data, image_data, multi_data = fake_post_data
# Video assert
self.assertTrue('downloadUrl' not in video_data['content']['media'])
self.assertEqual(video_data['commentary'], 'https://example.com/123')
# Image assert
self.assertEqual(image_data['content']['media']['downloadUrl'], 'https://example.com/456')
# Multi Image assert
self.assertEqual(multi_data['content']['multiImage']['images'][0]['downloadUrl'], 'https://example.com/789')