[REF] gamification: python tests and other improvements
bzr revid: mat@openerp.com-20131218111243-npnauv6mxhb4nttg
This commit is contained in:
parent
b63950e0dc
commit
e7887b8b8f
|
@ -20,4 +20,5 @@
|
|||
##############################################################################
|
||||
|
||||
import models
|
||||
import wizard
|
||||
import data
|
||||
|
|
|
@ -38,19 +38,16 @@ Both goals and badges are flexibles and can be adapted to a large range of modul
|
|||
""",
|
||||
|
||||
'data': [
|
||||
'views/challenge.xml',
|
||||
'wizard/update_goal.xml',
|
||||
'wizard/grant_badge.xml',
|
||||
'views/badge.xml',
|
||||
'views/challenge.xml',
|
||||
'views/goal.xml',
|
||||
'data/cron.xml',
|
||||
'security/gamification_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/goal_base.xml',
|
||||
'data/badge.xml',
|
||||
'wizard/update_goal.xml',
|
||||
'wizard/grant_badge.xml',
|
||||
],
|
||||
'test': [
|
||||
'test/goal_demo.yml'
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
|
|
|
@ -14,17 +14,6 @@
|
|||
<field name="res_id_field">user.id</field>
|
||||
</record>
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_base_avatar">
|
||||
<field name="name">Set your Avatar</field>
|
||||
<field name="description">In your user preference</field>
|
||||
<field name="computation_mode">manually</field>
|
||||
<field name="display_mode">checkbox</field>
|
||||
<!-- problem : default avatar != False -> manually + check in write function -->
|
||||
<field name="action_id" eval="ref('base.action_res_users_my')" />
|
||||
<field name="res_id_field">user.id</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="gamification.goal.definition" id="definition_base_company_data">
|
||||
<field name="name">Set your Company Data</field>
|
||||
<field name="description">Write some information about your company (specify at least a name)</field>
|
||||
|
@ -104,11 +93,6 @@
|
|||
<field name="target_goal">1</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_discover')" />
|
||||
</record>
|
||||
<record model="gamification.challenge.line" id="line_base_discover2">
|
||||
<field name="definition_id" eval="ref('definition_base_avatar')" />
|
||||
<field name="target_goal">1</field>
|
||||
<field name="challenge_id" eval="ref('challenge_base_discover')" />
|
||||
</record>
|
||||
|
||||
<record model="gamification.challenge.line" id="line_base_admin2">
|
||||
<field name="definition_id" eval="ref('definition_base_company_logo')" />
|
||||
|
|
|
@ -197,11 +197,30 @@ class gamification_challenge(osv.Model):
|
|||
'reward_failure': False,
|
||||
}
|
||||
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite the create method to add the user of groups"""
|
||||
|
||||
# add users when change the group auto-subscription
|
||||
if vals.get('autojoin_group_id'):
|
||||
new_group = self.pool.get('res.groups').browse(cr, uid, vals['autojoin_group_id'], context=context)
|
||||
|
||||
if 'user_ids' not in vals:
|
||||
vals['user_ids'] = []
|
||||
vals['user_ids'] += [(4, user.id) for user in new_group.users]
|
||||
|
||||
create_res = super(gamification_challenge, self).create(cr, uid, vals, context=context)
|
||||
|
||||
# subscribe new users to the challenge
|
||||
if vals.get('user_ids'):
|
||||
# done with browse after super to be sure catch all after orm process
|
||||
challenge = self.browse(cr, uid, create_res, context=context)
|
||||
self.message_subscribe_users(cr, uid, [challenge.id], [user.id for user in challenge.user_ids], context=context)
|
||||
|
||||
return create_res
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Overwrite the write method to add the user of groups"""
|
||||
if not ids:
|
||||
return True
|
||||
|
||||
# add users when change the group auto-subscription
|
||||
if vals.get('autojoin_group_id'):
|
||||
new_group = self.pool.get('res.groups').browse(cr, uid, vals['autojoin_group_id'], context=context)
|
||||
|
@ -306,6 +325,8 @@ class gamification_challenge(osv.Model):
|
|||
|
||||
Change the state of the challenge to in progress and generate related goals
|
||||
"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
# subscribe users if autojoin group
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
if challenge.autojoin_group_id:
|
||||
|
@ -320,6 +341,8 @@ class gamification_challenge(osv.Model):
|
|||
|
||||
Create goals that haven't been created yet (eg: if added users)
|
||||
Recompute the current value for each goal related"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
return self._update_all(cr, uid, ids=ids, context=context)
|
||||
|
||||
def action_close(self, cr, uid, ids, context=None):
|
||||
|
@ -342,6 +365,8 @@ class gamification_challenge(osv.Model):
|
|||
|
||||
Change the state of the challenge to draft
|
||||
Cancel the related goals"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
self.write(cr, uid, ids, {'state': 'draft'}, context=context)
|
||||
goal_ids = self.pool.get('gamification.goal').search(cr, uid, [('challenge_id', 'in', ids)], context=context)
|
||||
self.pool.get('gamification.goal').write(cr, uid, goal_ids, {'state': 'canceled'}, context=context)
|
||||
|
@ -350,6 +375,8 @@ class gamification_challenge(osv.Model):
|
|||
|
||||
def action_report_progress(self, cr, uid, ids, context=None):
|
||||
"""Manual report of a goal, does not influence automatic report frequency"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
for challenge in self.browse(cr, uid, ids, context):
|
||||
self.report_progress(cr, uid, challenge, context=context)
|
||||
return True
|
||||
|
@ -593,7 +620,7 @@ class gamification_challenge(osv.Model):
|
|||
result['res_id'] = challenge_id
|
||||
return result
|
||||
|
||||
def check_challenge_reward(self, cr, uid, challenge_ids, force=False, context=None):
|
||||
def check_challenge_reward(self, cr, uid, ids, force=False, context=None):
|
||||
"""Actions for the end of a challenge
|
||||
|
||||
If a reward was selected, grant it to the correct users.
|
||||
|
@ -603,8 +630,10 @@ class gamification_challenge(osv.Model):
|
|||
- when a challenge is manually closed
|
||||
(if no end date, a running challenge is never rewarded)
|
||||
"""
|
||||
if isinstance(ids, (int,long)):
|
||||
ids = [ids]
|
||||
context = context or {}
|
||||
for challenge in self.browse(cr, uid, challenge_ids, context=context):
|
||||
for challenge in self.browse(cr, uid, ids, context=context):
|
||||
(start_date, end_date) = start_end_date_for_period(challenge.period, challenge.start_date, challenge.end_date)
|
||||
yesterday = date.today() - timedelta(days=1)
|
||||
if end_date == yesterday.strftime(DF) or force:
|
||||
|
|
|
@ -307,7 +307,8 @@ class gamification_goal(osv.Model):
|
|||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite the create method to add a 'no_remind_goal' field to True"""
|
||||
context = context or {}
|
||||
if context is None:
|
||||
context = {}
|
||||
context['no_remind_goal'] = True
|
||||
return super(gamification_goal, self).create(cr, uid, vals, context=context)
|
||||
|
||||
|
@ -317,6 +318,8 @@ class gamification_goal(osv.Model):
|
|||
If the current value is changed and the report frequency is set to On
|
||||
change, a report is generated
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
vals['last_update'] = fields.date.today()
|
||||
result = super(gamification_goal, self).write(cr, uid, ids, vals, context=context)
|
||||
for goal in self.browse(cr, uid, ids, context=context):
|
||||
|
|
|
@ -31,6 +31,7 @@ class res_users_gamification_group(osv.Model):
|
|||
_inherit = ['res.users']
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""Overwrite to autosubscribe users if added to a group marked as autojoin, user will be added to challenge"""
|
||||
write_res = super(res_users_gamification_group, self).write(cr, uid, ids, vals, context=context)
|
||||
if vals.get('groups_id'):
|
||||
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
|
||||
|
@ -41,12 +42,20 @@ class res_users_gamification_group(osv.Model):
|
|||
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
|
||||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in ids]}, context=context)
|
||||
return write_res
|
||||
|
||||
if vals.get('image'):
|
||||
goal_definition_id = self.pool.get('ir.model.data').get_object(cr, uid, 'gamification', 'definition_base_avatar', context)
|
||||
goal_ids = self.pool.get('gamification.goal').search(cr, uid, [('definition_id', '=', goal_definition_id.id), ('user_id', 'in', ids)], context=context)
|
||||
values = {'state': 'reached', 'current': 1}
|
||||
self.pool.get('gamification.goal').write(cr, uid, goal_ids, values, context=context)
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
"""Overwrite to autosubscribe users if added to a group marked as autojoin, user will be added to challenge"""
|
||||
write_res = super(res_users_gamification_group, self).create(cr, uid, vals, context=context)
|
||||
if vals.get('groups_id'):
|
||||
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
|
||||
user_group_ids = [command[1] for command in vals['groups_id'] if command[0] == 4]
|
||||
user_group_ids += [id for command in vals['groups_id'] if command[0] == 6 for id in command[2]]
|
||||
|
||||
challenge_obj = self.pool.get('gamification.challenge')
|
||||
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
|
||||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, write_res)]}, context=context)
|
||||
return write_res
|
||||
|
||||
def get_goals_todo_info(self, cr, uid, context=None):
|
||||
|
@ -174,4 +183,3 @@ class res_groups_gamification_group(osv.Model):
|
|||
if challenge_ids:
|
||||
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in user_ids]}, context=context)
|
||||
return write_res
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
-
|
||||
In order to test process of the Goals, I assign the discovery challenge to all users
|
||||
-
|
||||
!record {model: gamification.challenge, id: challenge_base_discover}:
|
||||
autojoin_group_id: base.group_user
|
||||
-
|
||||
I verify that the users of the group are added (at least admin and demo)
|
||||
-
|
||||
!assert {model: gamification.challenge, id: challenge_base_discover, string: The autojoin function was not successful}:
|
||||
- len(user_ids) >= 2
|
||||
-
|
||||
I start the challenge and verify the change of state
|
||||
-
|
||||
!python {model: gamification.challenge}: |
|
||||
challenge = self.browse(cr, uid, ref('challenge_base_discover'))
|
||||
self.action_start(cr, uid, [challenge.id], context=context)
|
||||
assert challenge.state == 'inprogress', "Challenge failed the change of state"
|
||||
-
|
||||
I verify the goals are generated correctly
|
||||
-
|
||||
!python {model: gamification.goal}: |
|
||||
goal_ids = self.search(cr, uid, [('challenge_id', '=', ref('challenge_base_discover'))], context=context)
|
||||
assert len(goal_ids) >= 4, "Not enough goals have been generated"
|
||||
for goal in self.browse(cr, uid, goal_ids, context=context):
|
||||
assert goal.state != 'draft', "Draft goal have been generated"
|
||||
assert goal.line_id.challenge_id.id == ref('challenge_base_discover'), "Linked line incorrect"
|
||||
-
|
||||
I change timezone for demo user
|
||||
-
|
||||
!record {model: res.users, id: base.user_demo}:
|
||||
tz: "Europe/Brussels"
|
||||
-
|
||||
I check the goal for demo user is successful
|
||||
-
|
||||
!python {model: gamification.goal}: |
|
||||
goal_ids = self.search(cr, uid, [('user_id', '=', ref('base.user_demo')),('definition_id','=',ref('definition_base_timezone'))])
|
||||
self.update(cr, uid, goal_ids, context=context)
|
||||
for goal in self.browse(cr, uid, goal_ids, context=context):
|
||||
assert goal.state == "reached", "Goal not successful %s" % goal.state
|
||||
-
|
||||
I add a reward to the challenge
|
||||
-
|
||||
!record {model: gamification.challenge, id: challenge_base_discover}:
|
||||
reward_first_id: gamification.badge_good_job
|
||||
reward_failure: True
|
||||
-
|
||||
I check the demo user received the badge
|
||||
-
|
||||
!python {model: gamification.challenge}: |
|
||||
challenge = self.browse(cr, uid, ref('challenge_base_discover'), context=context)
|
||||
self.action_close(cr, uid, [challenge.id])
|
||||
badge_ids = self.pool.get('gamification.badge.user').search(cr, uid, [('badge_id', '=', ref('badge_good_job')), ('user_id', '=', ref('base.user_demo'))])
|
||||
assert badge_ids, "Demo users didn't received the badge"
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013 OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import test_challenge
|
||||
|
||||
checks = [
|
||||
test_challenge,
|
||||
]
|
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (c) 2013 OpenERP S.A. <http://openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class test_challenge(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(test_challenge, self).setUp()
|
||||
cr, uid = self.cr, self.uid
|
||||
self.data_obj = self.registry('ir.model.data')
|
||||
self.user_obj = self.registry('res.users')
|
||||
|
||||
self.challenge_obj = self.registry('gamification.challenge')
|
||||
self.line_obj = self.registry('gamification.challenge.line')
|
||||
self.goal_obj = self.registry('gamification.goal')
|
||||
self.badge_obj = self.registry('gamification.badge')
|
||||
self.badge_user_obj = self.registry('gamification.badge.user')
|
||||
|
||||
self.demo_user_id = self.data_obj.get_object_reference(cr, uid, 'base', 'user_demo')[1]
|
||||
self.group_user_id = self.data_obj.get_object_reference(cr, uid, 'base', 'group_user')[1]
|
||||
self.challenge_base_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'challenge_base_discover')[1]
|
||||
self.definition_timezone_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'definition_base_timezone')[1]
|
||||
self.badge_id = self.data_obj.get_object_reference(cr, uid, 'gamification', 'badge_good_job')[1]
|
||||
|
||||
def test_00_join_challenge(self):
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
user_ids = self.user_obj.search(cr, uid, [('groups_id', '=', self.group_user_id)])
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
|
||||
self.assertGreaterEqual(len(challenge.user_ids), len(user_ids), "Not enough users in base challenge")
|
||||
|
||||
self.user_obj.create(cr, uid, {
|
||||
'name': 'R2D2',
|
||||
'login': 'r2d2@openerp.com',
|
||||
'email': 'r2d2@openerp.com',
|
||||
'groups_id': [(6, 0, [self.group_user_id])]
|
||||
}, {'no_reset_password': True})
|
||||
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
self.assertGreaterEqual(len(challenge.user_ids), len(user_ids)+1, "These are not droids you are looking for")
|
||||
|
||||
def test_10_reach_challenge(self):
|
||||
cr, uid, context = self.cr, self.uid, {}
|
||||
|
||||
self.challenge_obj.action_start(cr, uid, [self.challenge_base_id], context=context)
|
||||
challenge = self.challenge_obj.browse(cr, uid, self.challenge_base_id, context=context)
|
||||
challenge_user_ids = [user.id for user in challenge.user_ids]
|
||||
|
||||
self.assertEqual(challenge.state, 'inprogress', "Challenge failed the change of state")
|
||||
|
||||
line_ids = self.line_obj.search(cr, uid, [('challenge_id', '=', self.challenge_base_id)], context=context)
|
||||
goal_ids = self.goal_obj.search(cr, uid, [('challenge_id', '=', self.challenge_base_id), ('state', '!=', 'draft')], context=context)
|
||||
self.assertEqual(len(goal_ids), len(line_ids)*len(challenge_user_ids), "Incorrect number of goals generated, should be 1 goal per user, per challenge line")
|
||||
|
||||
# demo user will set a timezone
|
||||
self.user_obj.write(cr, uid, self.demo_user_id, {'tz': "Europe/Brussels"}, context=context)
|
||||
goal_ids = self.goal_obj.search(cr, uid, [('user_id', '=', self.demo_user_id), ('definition_id', '=', self.definition_timezone_id)], context=context)
|
||||
|
||||
self.goal_obj.update(cr, uid, goal_ids, context=context)
|
||||
reached_goal_ids = self.goal_obj.search(cr, uid, [('id', 'in', goal_ids), ('state', '=', 'reached')], context=context)
|
||||
self.assertEqual(set(goal_ids), set(reached_goal_ids), "Not every goal was reached after changing timezone")
|
||||
|
||||
# reward for two firsts as admin may have timezone
|
||||
self.challenge_obj.write(cr, uid, self.challenge_base_id, {'reward_first_id': self.badge_id, 'reward_second_id': self.badge_id}, context=context)
|
||||
self.challenge_obj.action_close(cr, uid, self.challenge_base_id, context=context)
|
||||
|
||||
badge_ids = self.badge_user_obj.search(cr, uid, [('badge_id', '=', self.badge_id), ('user_id', '=', self.demo_user_id)])
|
||||
self.assertGreater(len(badge_ids), 0, "Demo user has not received the badge")
|
Loading…
Reference in New Issue