summaryrefslogtreecommitdiff
path: root/addons/gamification/tests
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/gamification/tests
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/gamification/tests')
-rw-r--r--addons/gamification/tests/__init__.py5
-rw-r--r--addons/gamification/tests/test_challenge.py75
-rw-r--r--addons/gamification/tests/test_karma_tracking.py315
3 files changed, 395 insertions, 0 deletions
diff --git a/addons/gamification/tests/__init__.py b/addons/gamification/tests/__init__.py
new file mode 100644
index 00000000..00174201
--- /dev/null
+++ b/addons/gamification/tests/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_challenge
+from . import test_karma_tracking
diff --git a/addons/gamification/tests/test_challenge.py b/addons/gamification/tests/test_challenge.py
new file mode 100644
index 00000000..d5875278
--- /dev/null
+++ b/addons/gamification/tests/test_challenge.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
+from odoo.exceptions import UserError
+
+
+class TestGamificationCommon(TransactionCaseWithUserDemo):
+
+ def setUp(self):
+ super(TestGamificationCommon, self).setUp()
+ employees_group = self.env.ref('base.group_user')
+ self.user_ids = employees_group.users
+
+ # Push demo user into the challenge before creating a new one
+ self.env.ref('gamification.challenge_base_discover')._update_all()
+ self.robot = self.env['res.users'].with_context(no_reset_password=True).create({
+ 'name': 'R2D2',
+ 'login': 'r2d2@openerp.com',
+ 'email': 'r2d2@openerp.com',
+ 'groups_id': [(6, 0, [employees_group.id])]
+ })
+ self.badge_good_job = self.env.ref('gamification.badge_good_job')
+
+
+class test_challenge(TestGamificationCommon):
+
+ def test_00_join_challenge(self):
+ challenge = self.env.ref('gamification.challenge_base_discover')
+ self.assertGreaterEqual(len(challenge.user_ids), len(self.user_ids), "Not enough users in base challenge")
+ challenge._update_all()
+ self.assertGreaterEqual(len(challenge.user_ids), len(self.user_ids)+1, "These are not droids you are looking for")
+
+ def test_10_reach_challenge(self):
+ Goals = self.env['gamification.goal']
+ challenge = self.env.ref('gamification.challenge_base_discover')
+
+ challenge.state = 'inprogress'
+ self.assertEqual(challenge.state, 'inprogress', "Challenge failed the change of state")
+
+ goal_ids = Goals.search([('challenge_id', '=', challenge.id), ('state', '!=', 'draft')])
+ self.assertEqual(len(goal_ids), len(challenge.line_ids) * len(challenge.user_ids.ids), "Incorrect number of goals generated, should be 1 goal per user, per challenge line")
+
+ demo = self.user_demo
+ # demo user will set a timezone
+ demo.tz = "Europe/Brussels"
+ goal_ids = Goals.search([('user_id', '=', demo.id), ('definition_id', '=', self.env.ref('gamification.definition_base_timezone').id)])
+
+ goal_ids.update_goal()
+
+ missed = goal_ids.filtered(lambda g: g.state != 'reached')
+ self.assertFalse(missed, "Not every goal was reached after changing timezone")
+
+ # reward for two firsts as admin may have timezone
+ badge_id = self.badge_good_job.id
+ challenge.write({'reward_first_id': badge_id, 'reward_second_id': badge_id})
+ challenge.state = 'done'
+
+ badge_ids = self.env['gamification.badge.user'].search([('badge_id', '=', badge_id), ('user_id', '=', demo.id)])
+ self.assertEqual(len(badge_ids), 1, "Demo user has not received the badge")
+
+
+class test_badge_wizard(TestGamificationCommon):
+
+ def test_grant_badge(self):
+ wiz = self.env['gamification.badge.user.wizard'].create({
+ 'user_id': self.env.user.id,
+ 'badge_id': self.badge_good_job.id,
+ })
+ with self.assertRaises(UserError, msg="A user cannot grant a badge to himself"):
+ wiz.action_grant_badge()
+ wiz.user_id = self.robot.id
+ self.assertTrue(wiz.action_grant_badge(), "Could not grant badge")
+
+ self.assertEqual(self.badge_good_job.stat_this_month, 1)
diff --git a/addons/gamification/tests/test_karma_tracking.py b/addons/gamification/tests/test_karma_tracking.py
new file mode 100644
index 00000000..8249daf3
--- /dev/null
+++ b/addons/gamification/tests/test_karma_tracking.py
@@ -0,0 +1,315 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from datetime import date
+from dateutil.relativedelta import relativedelta
+from unittest.mock import patch
+
+from odoo import exceptions, fields
+from odoo.addons.mail.tests.common import mail_new_test_user
+from odoo.tests import common
+
+
+class TestKarmaTrackingCommon(common.SavepointCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestKarmaTrackingCommon, cls).setUpClass()
+ cls.test_user = mail_new_test_user(
+ cls.env, login='test',
+ name='Test User', email='test@example.com',
+ karma=0,
+ groups='base.group_user',
+ )
+ cls.test_user_2 = mail_new_test_user(
+ cls.env, login='test2',
+ name='Test User 2', email='test2@example.com',
+ karma=0,
+ groups='base.group_user',
+ )
+ cls.env['gamification.karma.tracking'].search([]).unlink()
+
+ cls.test_date = fields.Date.today() + relativedelta(month=4, day=1)
+
+ @classmethod
+ def _create_trackings(cls, user, karma, steps, track_date, days_delta=1):
+ old_value = user.karma
+ for step in range(steps):
+ new_value = old_value + karma
+ cls.env['gamification.karma.tracking'].create([{
+ 'user_id': user.id,
+ 'old_value': old_value,
+ 'new_value': new_value,
+ 'consolidated': False,
+ 'tracking_date': fields.Date.to_string(track_date)
+ }])
+ old_value = new_value
+ track_date = track_date + relativedelta(days=days_delta)
+
+ def test_computation_gain(self):
+ self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30)
+ self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2)
+
+ results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([])
+ self.assertEqual(results[0]['user_id'], self.test_user_2.id)
+ self.assertEqual(results[0]['karma_gain_total'], 200)
+ self.assertEqual(results[0]['karma_position'], 1)
+ self.assertEqual(results[1]['user_id'], self.test_user.id)
+ self.assertEqual(results[1]['karma_gain_total'], 40)
+ self.assertEqual(results[1]['karma_position'], 2)
+
+ results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([], to_date=self.test_date + relativedelta(day=2))
+ self.assertEqual(results[0]['user_id'], self.test_user.id)
+ self.assertEqual(results[0]['karma_gain_total'], 20)
+ self.assertEqual(results[0]['karma_position'], 1)
+ self.assertEqual(results[1]['user_id'], self.test_user_2.id)
+ self.assertEqual(results[1]['karma_gain_total'], 10)
+ self.assertEqual(results[1]['karma_position'], 2)
+
+ results = (self.test_user | self.test_user_2)._get_tracking_karma_gain_position([], from_date=self.test_date + relativedelta(months=1, day=1))
+ self.assertEqual(results[0]['user_id'], self.test_user_2.id)
+ self.assertEqual(results[0]['karma_gain_total'], 50)
+ self.assertEqual(results[0]['karma_position'], 1)
+ self.assertEqual(results[1]['user_id'], self.test_user.id)
+ self.assertEqual(results[1]['karma_gain_total'], 20)
+ self.assertEqual(results[1]['karma_position'], 2)
+
+ results = self.env['res.users']._get_tracking_karma_gain_position([])
+ self.assertEqual(len(results), 0)
+
+ def test_consolidation_cron(self):
+ self.patcher = patch('odoo.addons.gamification.models.gamification_karma_tracking.fields.Date', wraps=fields.Date)
+ self.mock_datetime = self.patcher.start()
+ self.mock_datetime.today.return_value = date(self.test_date.year, self.test_date.month + 1, self.test_date.day)
+
+ self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30)
+ self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2)
+ self.env['gamification.karma.tracking']._consolidate_last_month()
+ consolidated = self.env['gamification.karma.tracking'].search([
+ ('user_id', 'in', (self.test_user | self.test_user_2).ids),
+ ('consolidated', '=', True),
+ ('tracking_date', '=', self.test_date)
+ ])
+ self.assertEqual(len(consolidated), 2)
+ unconsolidated = self.env['gamification.karma.tracking'].search([
+ ('user_id', 'in', (self.test_user | self.test_user_2).ids),
+ ('consolidated', '=', False),
+ ])
+ self.assertEqual(len(unconsolidated), 6) # 5 for test user 2, 1 for test user
+
+ self.patcher.stop()
+
+ def test_consolidation_monthly(self):
+ Tracking = self.env['gamification.karma.tracking']
+ base_test_user_karma = self.test_user.karma
+ base_test_user_2_karma = self.test_user_2.karma
+ self._create_trackings(self.test_user, 20, 2, self.test_date, days_delta=30)
+ self._create_trackings(self.test_user_2, 10, 20, self.test_date, days_delta=2)
+
+ Tracking._process_consolidate(self.test_date)
+ consolidated = Tracking.search([
+ ('user_id', '=', self.test_user_2.id),
+ ('consolidated', '=', True),
+ ('tracking_date', '=', self.test_date)
+ ])
+ self.assertEqual(len(consolidated), 1)
+ self.assertEqual(consolidated.old_value, base_test_user_2_karma) # 15 2-days span, from 1 to 29 included = 15 steps -> 150 karma
+ self.assertEqual(consolidated.new_value, base_test_user_2_karma + 150) # 15 2-days span, from 1 to 29 included = 15 steps -> 150 karma
+
+ remaining = Tracking.search([
+ ('user_id', '=', self.test_user_2.id),
+ ('consolidated', '=', False)
+ ])
+ self.assertEqual(len(remaining), 5) # 15 steps consolidated, remaining 5
+ self.assertEqual(remaining[0].tracking_date, self.test_date + relativedelta(months=1, day=9)) # ordering: last first
+ self.assertEqual(remaining[-1].tracking_date, self.test_date + relativedelta(months=1, day=1))
+
+ Tracking._process_consolidate(self.test_date + relativedelta(months=1))
+ consolidated = Tracking.search([
+ ('user_id', '=', self.test_user_2.id),
+ ('consolidated', '=', True),
+ ])
+ self.assertEqual(len(consolidated), 2)
+ self.assertEqual(consolidated[0].new_value, base_test_user_2_karma + 200) # 5 remaining 2-days span, from 1 to 9 included = 5 steps -> 50 karma
+ self.assertEqual(consolidated[0].old_value, base_test_user_2_karma + 150) # coming from previous iteration
+ self.assertEqual(consolidated[0].tracking_date, self.test_date + relativedelta(months=1)) # tracking set at beginning of month
+ self.assertEqual(consolidated[-1].new_value, base_test_user_2_karma + 150) # previously created one still present
+ self.assertEqual(consolidated[-1].old_value, base_test_user_2_karma) # previously created one still present
+
+ remaining = Tracking.search([
+ ('user_id', '=', self.test_user_2.id),
+ ('consolidated', '=', False)
+ ])
+ self.assertFalse(remaining)
+
+ # current user not-in-details tests
+ current_user_trackings = Tracking.search([
+ ('user_id', '=', self.test_user.id),
+ ])
+ self.assertEqual(len(current_user_trackings), 2)
+ self.assertEqual(current_user_trackings[0].new_value, base_test_user_karma + 40)
+ self.assertEqual(current_user_trackings[-1].old_value, base_test_user_karma)
+
+ def test_user_as_erp_manager(self):
+ self.test_user.write({'groups_id': [
+ (4, self.env.ref('base.group_partner_manager').id),
+ (4, self.env.ref('base.group_erp_manager').id)
+ ]})
+ user = self.env['res.users'].with_user(self.test_user).create({
+ 'name': 'Test Ostérone', 'karma': '32',
+ 'login': 'dummy', 'email': 'dummy@example.com',
+ })
+ with self.assertRaises(exceptions.AccessError):
+ user.read(['karma_tracking_ids'])
+
+ user.write({'karma': 60})
+ user.add_karma(10)
+ self.assertEqual(user.karma, 70)
+ trackings = self.env['gamification.karma.tracking'].sudo().search([('user_id', '=', user.id)])
+ self.assertEqual(len(trackings), 3) # create + write + add_karma
+
+ def test_user_tracking(self):
+ self.test_user.write({'groups_id': [
+ (4, self.env.ref('base.group_partner_manager').id),
+ (4, self.env.ref('base.group_system').id)
+ ]})
+ user = self.env['res.users'].with_user(self.test_user).create({
+ 'name': 'Test Ostérone', 'karma': '32',
+ 'login': 'dummy', 'email': 'dummy@example.com',
+ })
+ self.assertEqual(user.karma, 32)
+ self.assertEqual(len(user.karma_tracking_ids), 1)
+ self.assertEqual(user.karma_tracking_ids.old_value, 0)
+ self.assertEqual(user.karma_tracking_ids.new_value, 32)
+
+ user.write({'karma': 60})
+ user.add_karma(10)
+ self.assertEqual(user.karma, 70)
+ self.assertEqual(len(user.karma_tracking_ids), 3)
+ self.assertEqual(user.karma_tracking_ids[2].old_value, 60)
+ self.assertEqual(user.karma_tracking_ids[2].new_value, 70)
+ self.assertEqual(user.karma_tracking_ids[1].old_value, 32)
+ self.assertEqual(user.karma_tracking_ids[1].new_value, 60)
+ self.assertEqual(user.karma_tracking_ids[0].old_value, 0)
+ self.assertEqual(user.karma_tracking_ids[0].new_value, 32)
+
+
+class TestComputeRankCommon(common.SavepointCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestComputeRankCommon, cls).setUpClass()
+
+ def _patched_send_mail(*args, **kwargs):
+ pass
+
+ patch_email = patch('odoo.addons.mail.models.mail_template.MailTemplate.send_mail', _patched_send_mail)
+ patch_email.start()
+
+ cls.users = cls.env['res.users']
+ for k in range(-5, 1030, 30):
+ cls.users += mail_new_test_user(
+ cls.env,
+ name=str(k),
+ login="test_recompute_rank_%s" % k,
+ karma=k,
+ )
+
+ cls.env['gamification.karma.rank'].search([]).unlink()
+
+ cls.rank_1 = cls.env['gamification.karma.rank'].create({
+ 'name': 'rank 1',
+ 'karma_min': 1,
+ })
+
+ cls.rank_2 = cls.env['gamification.karma.rank'].create({
+ 'name': 'rank 2',
+ 'karma_min': 250,
+ })
+
+ cls.rank_3 = cls.env['gamification.karma.rank'].create({
+ 'name': 'rank 3',
+ 'karma_min': 500,
+ })
+ cls.rank_4 = cls.env['gamification.karma.rank'].create({
+ 'name': 'rank 4',
+ 'karma_min': 1000,
+ })
+
+ patch_email.stop()
+
+ def test_00_initial_compute(self):
+
+ self.assertEqual(len(self.users), 35)
+
+ self.assertEqual(
+ len(self.rank_1.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_1.karma_min and u.karma < self.rank_2.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_2.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_2.karma_min and u.karma < self.rank_3.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_3.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_3.karma_min and u.karma < self.rank_4.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_4.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_4.karma_min])
+ )
+
+ def test_01_switch_rank(self):
+
+ self.assertEqual(len(self.users), 35)
+
+ self.rank_3.karma_min = 100
+ # rank_1 -> rank_3 -> rank_2 -> rank_4
+
+ self.assertEqual(
+ len(self.rank_1.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_1.karma_min and u.karma < self.rank_3.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_3.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_3.karma_min and u.karma < self.rank_2.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_2.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_2.karma_min and u.karma < self.rank_4.karma_min])
+ )
+ self.assertEqual(
+ len(self.rank_4.user_ids & self.users),
+ len([u for u in self.users if u.karma >= self.rank_4.karma_min])
+ )
+
+ def test_02_update_rank_without_switch(self):
+ number_of_users = False
+
+ def _patched_recompute_rank(_self, *args, **kwargs):
+ nonlocal number_of_users
+ number_of_users = len(_self & self.users)
+
+ patch_bulk = patch('odoo.addons.gamification.models.res_users.Users._recompute_rank', _patched_recompute_rank)
+ patch_bulk.start()
+ self.rank_3.karma_min = 700
+ self.assertEqual(number_of_users, 7, "Should just recompute for the 7 users between 500 and 700")
+ patch_bulk.stop()
+
+ def test_03_test_bulk_call(self):
+ self.assertEqual(len(self.users), 35)
+
+ def _patched_check_in_bulk(*args, **kwargs):
+ raise
+
+ patch_bulk = patch('odoo.addons.gamification.models.res_users.Users._recompute_rank_bulk', _patched_check_in_bulk)
+ patch_bulk.start()
+
+ # call on 5 users should not trigger the bulk function
+ self.users[0:5]._recompute_rank()
+
+ # call on 50 users should trigger the bulk function
+ with self.assertRaises(Exception):
+ self.users[0:50]._recompute_rank()
+
+ patch_bulk.stop()