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

137 lines
6.2 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import datetime
import random
from unittest.mock import patch
from odoo import fields
from odoo.addons.base.tests.test_ir_cron import CronMixinCase
from odoo.addons.social.tests.common import SocialCase
from odoo.addons.social.models.social_post import SocialPost
from odoo.addons.social_push_notifications.models.social_account import SocialAccountPushNotifications
class SocialPushNotificationsCase(SocialCase, CronMixinCase):
@classmethod
def setUpClass(cls):
super(SocialPushNotificationsCase, cls).setUpClass()
cls.website_1 = cls.env['website'].create({
'name': 'Website 1 WITHOUT push notifications',
'domain': 'website1.example.com',
'firebase_enable_push_notifications': False,
})
cls.website_2 = cls.env['website'].create({
'name': 'Website 2 WITH push notifications',
'domain': 'website2.example.com',
'firebase_enable_push_notifications': True,
'firebase_use_own_account': True,
'firebase_admin_key_file': base64.b64encode(b'{}')
})
cls.website_3 = cls.env['website'].create({
'name': 'Website 3 WITH push notifications',
'domain': 'website3.example.com',
'firebase_enable_push_notifications': True,
'firebase_use_own_account': True,
'firebase_admin_key_file': base64.b64encode(b'{}')
})
cls.websites = cls.website_1 | cls.website_2 | cls.website_3
cls.social_accounts = cls.env['social.account'].search(
[('website_id', 'in', cls.websites.ids)]
)
cls.social_post.invalidate_model(['account_allowed_ids'])
cls.social_post.write({
'account_ids': [(6, 0, cls.social_accounts.filtered(lambda a: a.website_id.id != cls.website_3.id).ids)],
})
def test_post(self):
""" Test a full flow of posting social_push_notifications.
We trigger the send method of the post and check that it does all the way to the Firebase
sending calls. """
# Create some visitors with or without push_token in different timezone (or no timezone)
timezones = ['Europe/Brussels', 'America/New_York', 'Asia/Vladivostok', False]
Visitor = self.env['website.visitor']
visitor_vals = []
for i in range(0, 4):
visitor_vals.append({
'name': timezones[i] or 'Visitor',
'timezone': timezones[i],
'access_token': '%032x' % random.randrange(16**32),
'push_subscription_ids': [(0, 0, {'push_token': 'fake_token_%s' % i})] if i != 0 else False,
'website_id': self.websites[i].id if i != 3 else False,
})
self.visitors = Visitor.create(visitor_vals)
self.social_post.create_uid.write({'tz': timezones[0]})
# Since mocking a decorated method doesn't work, we unset the constrains
# before creating the post and re-apply them after.
check_scheduled_date_constrains = SocialPost._check_scheduled_date._constrains
SocialPost._check_scheduled_date._constrains = tuple()
scheduled_date = fields.Datetime.now() - datetime.timedelta(minutes=1)
with self.capture_triggers('social.ir_cron_post_scheduled') as captured_triggers:
self.social_post.write({
'use_visitor_timezone': True,
'post_method': 'scheduled',
'scheduled_date': scheduled_date
})
SocialPost._check_scheduled_date._constrains = check_scheduled_date_constrains
# when scheduling, a CRON trigger is created to match the scheduled_date
self.assertEqual(len(captured_triggers.records), 1)
captured_trigger = captured_triggers.records[0]
self.assertEqual(captured_trigger.call_at, scheduled_date)
self.assertEqual(captured_trigger.cron_id, self.env.ref('social.ir_cron_post_scheduled'))
self.assertEqual(self.social_post.state, 'draft')
with self.capture_triggers('social.ir_cron_post_scheduled') as captured_triggers:
self.social_post._action_post() # begin the post process
# as the post_method is 'scheduled', a CRON trigger should not be created, we already have one
self.assertEqual(len(captured_triggers.records), 0)
# check that live posts are correctly created
live_posts = self.env['social.live.post'].search([('post_id', '=', self.social_post.id)])
self.assertEqual(len(live_posts), 2)
self.assertTrue(all(live_post.state == 'ready' for live_post in live_posts))
self.assertEqual(self.social_post.state, 'posting')
def _firebase_send_message_from_configuration(_this, _data, visitors):
website = visitors.website_id
push_enabled = website.firebase_enable_push_notifications
# Ensure that only visitors from the website with push notifications enabled
# and linked to the social account are notified
self.assertEqual(len(visitors), 1 if push_enabled else 0)
if visitors:
self.assertEqual(visitors.website_id, self.website_2)
return visitors.mapped('push_subscription_ids.push_token'), []
with patch.object(SocialAccountPushNotifications, '_firebase_send_message_from_configuration',
_firebase_send_message_from_configuration):
live_posts._post_push_notifications()
self.assertFalse(all(live_post.state == 'posted' for live_post in live_posts))
self.assertEqual(self.social_post.state, 'posting')
# simulate that everyone can receive the push notif (because their time >= time of the one who created the post)
self.visitors.write({'timezone': self.env.user.tz})
with patch.object(SocialAccountPushNotifications, '_firebase_send_message_from_configuration',
_firebase_send_message_from_configuration):
live_posts._post_push_notifications()
self._checkPostedStatus(True)
@classmethod
def _get_social_media(cls):
return cls.env.ref('social_push_notifications.social_media_push_notifications')