File: test_statistics.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (267 lines) | stat: -rw-r--r-- 12,687 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# -*- 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)