File: test_gamification_karma.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 (164 lines) | stat: -rw-r--r-- 7,318 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
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo.addons.website_slides.tests import common
from odoo.tests import tagged
from odoo.tests.common import users
from odoo.tools import mute_logger


@tagged('gamification')
class TestKarmaGain(common.SlidesCase):

    def setUp(self):
        super(TestKarmaGain, self).setUp()

        self.channel_2 = self.env['slide.channel'].with_user(self.user_officer).create({
            'name': 'Test Channel 2',
            'channel_type': 'training',
            'promote_strategy': 'most_voted',
            'enroll': 'public',
            'visibility': 'public',
            'is_published': True,
            'karma_gen_channel_finish': 100,
            'karma_gen_channel_rank': 10,
        })

        self.slide_2_0, self.slide_2_1 = self.env['slide.slide'].with_user(self.user_officer).create([
            {'name': 'How to travel through space and time',
             'channel_id': self.channel_2.id,
             'slide_category': 'document',
             'is_published': True,
             'completion_time': 2.0,
            },
            {'name': 'How to duplicate yourself',
             'channel_id': self.channel_2.id,
             'slide_category': 'document',
             'is_published': True,
             'completion_time': 2.0,
            }
        ])

    @mute_logger('odoo.models')
    @users('user_emp', 'user_portal', 'user_officer')
    def test_karma_gain(self):
        user = self.env.user
        user.write({'karma': 0})
        computed_karma = 0

        # Add the user to the course
        (self.channel | self.channel_2)._action_add_members(user.partner_id)
        self.assertEqual(user.karma, 0)

        # Finish the Course
        self.slide.with_user(user).action_mark_completed()
        self.assertFalse(self.channel.with_user(user).completed)
        self.slide_2.with_user(user).action_mark_completed()

        # answer a quizz question
        self.slide_3.with_user(user).action_set_viewed(quiz_attempts_inc=True)
        self.slide_3.with_user(user)._action_mark_completed()
        computed_karma += self.slide_3.quiz_first_attempt_reward
        computed_karma += self.channel.karma_gen_channel_finish
        self.assertTrue(self.channel.with_user(user).completed)
        self.assertEqual(user.karma, computed_karma)

        # Mark the quiz as not completed.
        # The course remains completed once completed. No karma change.
        self.slide_3.with_user(user).action_mark_uncompleted()
        computed_karma -= self.slide_3.quiz_first_attempt_reward
        self.assertTrue(self.channel.with_user(user).completed)
        self.assertEqual(user.karma, computed_karma)

        # Re-submit the quiz, we should consider it as the second attempt
        self.slide_3.with_user(user).action_set_viewed(quiz_attempts_inc=True)
        self.slide_3.with_user(user)._action_mark_completed()
        computed_karma += self.slide_3.quiz_second_attempt_reward
        self.assertTrue(self.channel.with_user(user).completed)
        self.assertEqual(user.karma, computed_karma)

        # Begin then finish the second Course
        self.slide_2_0.with_user(user).action_mark_completed()
        self.assertFalse(self.channel_2.with_user(user).completed)
        self.assertEqual(user.karma, computed_karma)

        self.slide_2_1.with_user(user).action_mark_completed()
        self.assertTrue(self.channel_2.with_user(user).completed)
        computed_karma += self.channel_2.karma_gen_channel_finish
        self.assertEqual(user.karma, computed_karma)

        # Vote for a slide: Karma should not move
        slide_user = self.slide.with_user(user)
        slide_user.action_like()
        self.assertEqual(user.karma, computed_karma)

        slide_user.action_dislike()
        self.assertEqual(user.karma, computed_karma)

        # Leave the finished course - karma should not move as we only archive membership
        self.channel._remove_membership(user.partner_id.ids)
        self.assertEqual(user.karma, computed_karma)

        # Unarchive the partner. Karma should not move. Course should be completed.
        self.channel._action_add_members(user.partner_id)
        self.assertTrue(self.channel_2.with_user(user).completed)
        self.assertEqual(user.karma, computed_karma)

    @mute_logger('odoo.models')
    @users('user_emp', 'user_portal', 'user_officer')
    def test_karma_gain_multiple_course(self):
        user = self.env.user
        user.write({'karma': 0})
        computed_karma = 0

        # Finish two course at the same time (should not ever happen but hey, we never know)
        (self.channel | self.channel_2)._action_add_members(user.partner_id)

        computed_karma += self.channel.karma_gen_channel_finish + self.channel_2.karma_gen_channel_finish
        (self.slide | self.slide_2 | self.slide_3 | self.slide_2_0 | self.slide_2_1).with_user(user)._action_mark_completed()
        self.assertEqual(user.karma, computed_karma)

    @mute_logger('odoo.models')
    def test_karma_gain_multiple_course_multiple_users(self):
        users = self.user_emp | self.user_portal
        users.write({'karma': 0})

        (self.channel | self.channel_2)._action_add_members(users.partner_id)
        channel_partners = self.env['slide.channel.partner'].sudo().search([('partner_id', 'in', users.partner_id.ids)])
        self.assertEqual(len(channel_partners), 4)

        # Set courses as completed and update karma
        with self.assertQueryCount(57):  # com 55
            channel_partners._post_completion_update_hook()

        computed_karma = self.channel.karma_gen_channel_finish + self.channel_2.karma_gen_channel_finish

        for user in users:
            self.assertEqual(user.karma, computed_karma)
            user_trackings = user.karma_tracking_ids
            self.assertEqual(len(user_trackings), 2)

            self.assertEqual(user_trackings[0].new_value, computed_karma)
            self.assertEqual(user_trackings[0].old_value, self.channel_2.karma_gen_channel_finish)
            self.assertEqual(user_trackings[0].origin_ref, self.channel_2)

            self.assertEqual(user_trackings[1].new_value, self.channel.karma_gen_channel_finish)
            self.assertEqual(user_trackings[1].old_value, 0)
            self.assertEqual(user_trackings[1].origin_ref, self.channel)

        # now, remove the membership in batch, on multiple users - karma should not move as we only archive membership
        with self.assertQueryCount(10):
            (self.channel | self.channel_2)._remove_membership(users.partner_id.ids)

        for user in users:
            self.assertEqual(user.karma, computed_karma)
            user_trackings = user.karma_tracking_ids
            self.assertEqual(len(user_trackings), 2)

            self.assertEqual(user_trackings[0].new_value, computed_karma)
            self.assertEqual(user_trackings[0].old_value, self.channel.karma_gen_channel_finish)
            self.assertEqual(user_trackings[0].origin_ref, self.channel_2)

            self.assertEqual(user_trackings[1].new_value, self.channel.karma_gen_channel_finish)
            self.assertEqual(user_trackings[1].old_value, 0)
            self.assertEqual(user_trackings[1].origin_ref, self.channel)