website_slides/tests/test_statistics.py

268 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import math
from dateutil.relativedelta import relativedelta
from odoo import fields
from odoo.addons.website_slides.tests import common
from odoo.exceptions import UserError
from odoo.tests import HttpCase, tagged
from odoo.tests.common import users
from odoo.tools import mute_logger, float_compare
@tagged('functional')
class TestChannelStatistics(common.SlidesCase):
@mute_logger('odoo.models')
def test_channel_new_content(self):
(self.slide | self.slide_2).write({'date_published': fields.Datetime.now() + relativedelta(days=-6)})
self.slide_3.write({'date_published': fields.Datetime.now() + relativedelta(days=-8)})
self.assertTrue(all(slide.is_new_slide for slide in (self.slide | self.slide_2)))
self.assertFalse(self.slide_3.is_new_slide)
channel_aspublisher = self.channel.with_user(self.user_officer)
self.assertTrue(channel_aspublisher.partner_has_new_content)
(self.slide | self.slide_2).with_user(self.user_officer).action_mark_completed()
self.assertFalse(channel_aspublisher.partner_has_new_content)
channel_aspublisher._action_add_members(self.user_portal.partner_id)
channel_asportal = self.channel.with_user(self.user_portal)
self.assertTrue(channel_asportal.partner_has_new_content)
(self.slide | self.slide_2).write({'date_published': fields.Datetime.now() + relativedelta(days=-8)})
channel_asportal.invalidate_recordset(['partner_has_new_content'])
self.assertFalse(channel_asportal.partner_has_new_content)
@mute_logger('odoo.models')
def test_channel_statistics(self):
channel_publisher = self.channel.with_user(self.user_officer)
# slide category computation
self.assertEqual(channel_publisher.total_slides, len(channel_publisher.slide_content_ids))
self.assertEqual(channel_publisher.nbr_infographic, len(channel_publisher.slide_content_ids.filtered(lambda s: s.slide_category == 'infographic')))
self.assertEqual(channel_publisher.nbr_document, len(channel_publisher.slide_content_ids.filtered(lambda s: s.slide_category == 'document')))
self.assertEqual(channel_publisher.nbr_video, len(channel_publisher.slide_content_ids.filtered(lambda s: s.slide_category == 'video')))
# slide statistics computation
self.assertEqual(float_compare(channel_publisher.total_time, sum(s.completion_time for s in channel_publisher.slide_content_ids), 3), 0)
# members computation
self.assertEqual(channel_publisher.members_all_count, 1)
channel_publisher._action_add_members(self.user_officer.partner_id)
self.assertEqual(channel_publisher.members_all_count, 1)
channel_publisher._action_add_members(self.user_emp.partner_id)
channel_publisher.invalidate_recordset(['partner_ids'])
self.assertEqual(channel_publisher.members_all_count, 2)
self.assertEqual(channel_publisher.partner_ids, self.user_officer.partner_id | self.user_emp.partner_id)
@mute_logger('odoo.models')
def test_channel_user_statistics(self):
channel_publisher = self.channel.with_user(self.user_officer)
channel_publisher.write({
'enroll': 'invite',
})
channel_publisher._action_add_members(self.user_emp.partner_id)
channel_emp = self.channel.with_user(self.user_emp)
members = self.env['slide.channel.partner'].search([('channel_id', '=', self.channel.id)])
member_emp = members.filtered(lambda m: m.partner_id == self.user_emp.partner_id)
member_publisher = members.filtered(lambda m: m.partner_id == self.user_officer.partner_id)
slides_emp = (self.slide | self.slide_2).with_user(self.user_emp)
slides_emp.action_set_viewed()
self.assertEqual(member_emp.completion, 0)
self.assertEqual(channel_emp.completion, 0)
slides_emp.action_mark_completed()
channel_emp.invalidate_recordset()
self.assertEqual(
channel_emp.completion,
math.ceil(100.0 * len(slides_emp) / len(channel_publisher.slide_content_ids)))
self.assertFalse(channel_emp.completed)
self.slide_3.with_user(self.user_emp)._action_mark_completed()
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertTrue(channel_emp.completed)
# The following tests should not update the completion for users that has already completed the course
self.slide_3.is_published = False
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertTrue(channel_emp.completed)
self.slide_3.is_published = True
self.slide_3.active = False
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertTrue(channel_emp.completed)
# Should update completion when slide is marked as completed
self.assertEqual(member_publisher.completion, 0)
self.assertEqual(channel_publisher.completion, 0)
self.slide.with_user(self.user_officer).action_mark_completed()
self.assertEqual(member_publisher.completion, 50)
self.assertEqual(channel_publisher.completion, 50)
# Should update completion when slide is (un)archived
self.slide_3.active = True
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertEqual(member_publisher.completion, 33)
self.assertEqual(channel_publisher.completion, 33)
# Should update completion when a new published slide is created
self.slide_4 = self.slide_3.copy({'is_published': True})
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertEqual(member_publisher.completion, 25)
self.assertEqual(channel_publisher.completion, 25)
# Should update completion when slide is (un)published
self.slide_4.is_published = False
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertEqual(member_publisher.completion, 33)
self.assertEqual(channel_publisher.completion, 33)
self.slide_4.is_published = True
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertEqual(member_publisher.completion, 25)
self.assertEqual(channel_publisher.completion, 25)
# Should update completion when a slide is unlinked
self.slide_4.with_user(self.user_manager).unlink()
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertEqual(member_publisher.completion, 33)
self.assertEqual(channel_publisher.completion, 33)
# Should update completion when slide is marked as uncompleted
slide_emp = self.slide.with_user(self.user_emp)
slide_emp.action_mark_uncompleted()
self.assertEqual(member_emp.completion, 100)
self.assertEqual(channel_emp.completion, 100)
self.assertTrue(channel_emp.completed)
self.assertFalse(slide_emp.user_membership_id.completed)
self.slide.invalidate_model(['user_has_completed'])
slide_publisher = self.slide.with_user(self.user_officer)
slide_publisher.action_mark_uncompleted()
self.assertEqual(member_publisher.completion, 0)
self.assertEqual(channel_publisher.completion, 0)
self.assertFalse(channel_publisher.completed)
self.assertFalse(slide_emp.user_membership_id.completed)
@mute_logger('odoo.models')
def test_channel_user_statistics_complete_check_member(self):
slides = (self.slide | self.slide_2)
slides.write({'is_preview': True})
slides.flush_model()
slides_emp = slides.with_user(self.user_emp)
slides_emp.read(['name'])
with self.assertRaises(UserError):
slides_emp.action_mark_completed()
@mute_logger('odoo.models')
def test_channel_user_statistics_view_check_member(self):
slides = (self.slide | self.slide_2)
slides.write({'is_preview': True})
slides.flush_model()
slides_emp = slides.with_user(self.user_emp)
slides_emp.read(['name'])
with self.assertRaises(UserError):
slides_emp.action_set_viewed()
@tagged('functional')
class TestSlideStatistics(common.SlidesCase):
def test_slide_user_statistics(self):
channel_publisher = self.channel.with_user(self.user_officer)
channel_publisher._action_add_members(self.user_emp.partner_id)
channel_publisher.invalidate_recordset(['partner_ids'])
slide_emp = self.slide.with_user(self.user_emp)
self.assertEqual(slide_emp.likes, 0)
self.assertEqual(slide_emp.dislikes, 0)
self.assertEqual(slide_emp.user_vote, 0)
slide_emp.action_like()
self.assertEqual(slide_emp.likes, 1)
self.assertEqual(slide_emp.dislikes, 0)
self.assertEqual(slide_emp.user_vote, 1)
slide_emp.action_dislike()
self.assertEqual(slide_emp.likes, 0)
self.assertEqual(slide_emp.dislikes, 1)
self.assertEqual(slide_emp.user_vote, -1)
slide_emp.action_dislike()
self.assertEqual(slide_emp.likes, 0)
self.assertEqual(slide_emp.dislikes, 0)
self.assertEqual(slide_emp.user_vote, 0)
def test_slide_statistics_views(self):
channel_publisher = self.channel.with_user(self.user_officer)
channel_publisher._action_add_members(self.user_emp.partner_id)
self.assertEqual(self.slide.slide_views, 0)
self.assertEqual(self.slide.public_views, 0)
self.slide.write({'public_views': 4})
self.assertEqual(self.slide.slide_views, 0)
self.assertEqual(self.slide.public_views, 4)
self.assertEqual(self.slide.total_views, 4)
slide_emp = self.slide.with_user(self.user_emp)
slide_emp.action_set_viewed()
self.assertEqual(slide_emp.slide_views, 1)
self.assertEqual(slide_emp.public_views, 4)
self.assertEqual(slide_emp.total_views, 5)
@users('user_officer')
def test_slide_statistics_categories(self):
category = self.category.with_user(self.env.user)
self.assertEqual(
category.nbr_document,
len(category.channel_id.slide_ids.filtered(lambda s: s.category_id == category and s.slide_category == 'document')))
self.assertEqual(self.channel.total_slides, 3, 'The channel should contain 3 slides')
self.assertEqual(category.total_slides, 2, 'The first category should contain 2 slides')
self.assertEqual(category.completion_time, 4.5, 'The first category should be 4.5 hours long')
other_category = self.env['slide.slide'].with_user(self.user_officer).create({
'name': 'Other Category',
'channel_id': self.channel.id,
'is_category': True,
'is_published': True,
'sequence': 5,
})
self.assertEqual(other_category.total_slides, 0, 'The other category should not contain any slide yet')
# move one of the slide to the other category
self.slide_3.write({'sequence': 6})
self.assertEqual(category.total_slides, 1, 'The first category should contain 1 slide')
self.assertEqual(other_category.total_slides, 1, 'The other category should contain 1 slide')
self.assertEqual(self.channel.total_slides, 3, 'The channel should still contain 3 slides')
@tagged('functional')
class TestHttpSlideStatistics(HttpCase, common.SlidesCase):
@classmethod
def setUpClass(cls):
super(TestHttpSlideStatistics, cls).setUpClass()
cls.slide.is_preview = True
def test_slide_statistics_views(self):
self.assertEqual(self.slide.public_views, 0)
self.assertEqual(self.slide.total_views, 0)
# Open the slide a first time. Must increase the views by 1
self.url_open(f'/slides/slide/{self.slide.id}')
self.assertEqual(self.slide.public_views, 1)
self.assertEqual(self.slide.total_views, 1)
# Open the slide a second time.
# As it's the same session, it must not increase the views anymore
self.url_open(f'/slides/slide/{self.slide.id}')
self.assertEqual(self.slide.public_views, 1)
self.assertEqual(self.slide.total_views, 1)