Files
enterprise-addons/test_web_cohort/tests/test_web_cohort.py
T

317 lines
15 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
from odoo import fields
from odoo.tests import common
TYPE_SIZE = 8
TYPE = ['Type %s' % i for i in range(1,TYPE_SIZE + 1)]
NB_START_DAY = 15
NB_END_DAY = 30
START_DATE = datetime.datetime(2018,12,1,0,0,0)
class TestCohortCommon(common.TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.CohortType = cls.env['web.cohort.type']
cls.WebCohortSimpleModel = cls.env['web.cohort.simple.model']
cls.type_ids = []
for t in TYPE:
cls.type_ids.append(cls.CohortType.create({'name': t}).id)
class TestCohortForward(TestCohortCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
start_date = START_DATE
end_date = start_date
data_list = []
for i in range(0,NB_START_DAY): #Start date on 20 days
for j in range(0,NB_END_DAY):
data = {
'name': "[%s:%s]" % (i, j),
'type_id': cls.type_ids[int(TYPE_SIZE * j / NB_END_DAY)],
'datetime_start': start_date,
'datetime_stop': end_date,
'date_start': fields.Date.to_date(start_date),
'date_stop': fields.Date.to_date(end_date),
'revenue': j * 10,
}
data_list.append(data)
end_date = end_date + datetime.timedelta(days=3)
start_date = start_date + datetime.timedelta(days=5)
end_date = start_date
cls.WebCohortSimpleModel.create(data_list)
def test_forward_datetime(self):
#Test interval
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'year', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 2)
self.assertEqual(result[0]['columns'][0]['percentage'], 81)
self.assertEqual(result[0]['columns'][1]['percentage'], 0)
#Test when start date of column is > Today
self.assertEqual(result[0]['columns'][14]['percentage'], '')
#Since percentage is 0 at second year, churn value should be equal to total value
self.assertEqual(result[0]['columns'][1]['churn_value'], result[0]['value'])
#Total of value of each row should be equal to the number of data generated
self.assertEqual(result[0]['value'] + result[1]['value'], NB_START_DAY * NB_END_DAY)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'month', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 3)
self.assertEqual(result[0]['columns'][0]['percentage'], 81)
self.assertEqual(result[0]['columns'][1]['percentage'], 46.7)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'week', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 11)
self.assertEqual(result[0]['columns'][0]['percentage'], 96.7)
self.assertEqual(result[0]['columns'][1]['percentage'], 90.0)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'day', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), NB_START_DAY)
self.assertEqual(result[0]['columns'][0]['percentage'], 96.7)
self.assertEqual(result[0]['columns'][1]['percentage'], 96.7)
#Test measure
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'revenue', 'week', [], 'retention', 'forward')['rows']
#Sum of value should be 0 + 10 + 20 + ... + 390 * 20, (gaussian sum 0 to 39) * 10 * 20
self.assertEqual(sum(v['value'] for v in result), (29 * 30 / 2) * 10 * NB_START_DAY)
#Percentage should be different from count measure and value as well
self.assertEqual(result[0]['columns'][0]['percentage'], 100.0)
self.assertEqual(result[0]['columns'][1]['percentage'], 99.3)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'type_id', 'week', [], 'retention', 'forward')['rows']
#There is 8 type so value should be 8
self.assertEqual(result[0]['value'], TYPE_SIZE)
#Test Churn mode
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'year', [], 'churn', 'forward')['rows']
#Percentage is 100 - rentention %
self.assertEqual(result[0]['columns'][0]['percentage'], round(100 - 81, 2))
self.assertEqual(result[0]['columns'][1]['percentage'], 100 - 0)
def test_forward_date(self):
#Test interval
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'__count', 'year', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 2)
self.assertEqual(result[0]['columns'][0]['percentage'], 81)
self.assertEqual(result[0]['columns'][1]['percentage'], 0)
#Test when start date of column is > Today
self.assertEqual(result[0]['columns'][14]['percentage'], '')
#Since percentage is 0 at second year, churn value should be equal to total value
self.assertEqual(result[0]['columns'][1]['churn_value'], result[0]['value'])
#Total of value of each row should be equal to the number of data generated
self.assertEqual(result[0]['value'] + result[1]['value'], NB_START_DAY * NB_END_DAY)
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'__count', 'month', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 3)
self.assertEqual(result[0]['columns'][0]['percentage'], 81)
self.assertEqual(result[0]['columns'][1]['percentage'], 46.7)
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'__count', 'week', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), 11)
self.assertEqual(result[0]['columns'][0]['percentage'], 96.7)
self.assertEqual(result[0]['columns'][1]['percentage'], 90.0)
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'__count', 'day', [], 'retention', 'forward')['rows']
self.assertEqual(len(result), NB_START_DAY)
self.assertEqual(result[0]['columns'][0]['percentage'], 96.7)
self.assertEqual(result[0]['columns'][1]['percentage'], 96.7)
#Test measure
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'revenue', 'week', [], 'retention', 'forward')['rows']
#Sum of value should be 0 + 10 + 20 + ... + 390 * 20, (gaussian sum 0 to 39) * 10 * 20
self.assertEqual(sum(v['value'] for v in result), (29 * 30 / 2) * 10 * NB_START_DAY)
#Percentage should be different from count measure and value as well
self.assertEqual(result[0]['columns'][0]['percentage'], 100.0)
self.assertEqual(result[0]['columns'][1]['percentage'], 99.3)
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'type_id', 'week', [], 'retention', 'forward')['rows']
#There is 8 type so value should be 8
self.assertEqual(result[0]['value'], TYPE_SIZE)
#Test Churn mode
result = self.WebCohortSimpleModel.get_cohort_data("date_start", "date_stop",
'__count', 'year', [], 'churn', 'forward')['rows']
#Percentage is 100 - rentention %
self.assertEqual(result[0]['columns'][0]['percentage'], round(100 - 81, 2))
self.assertEqual(result[0]['columns'][1]['percentage'], 100 - 0)
def test_empty_data(self):
""" In some reports, some columns can be empty.
Say a model "event", with a field "rating_ids" (relation) and a field "avg_rating" (float related).
If an event has no rating, it would make sense that its "avg_rating" is False rather than 0.
In this case, the event shouldn't be displayed in the cohort.
"""
start_date = START_DATE - datetime.timedelta(weeks=1)
self.WebCohortSimpleModel.create([{
'name': "no revenue",
'date_start': start_date,
'date_stop': start_date + datetime.timedelta(days=i),
} for i in range(7)])
result = self.WebCohortSimpleModel.with_context(test_empty_data=True).get_cohort_data(
'date_start', 'date_stop', 'revenue', 'week', [], 'retention', 'forward'
)
self.assertNotIn(
'W47 2018', (row['date'] for row in result['rows']),
'Empty data should not be displayed',
)
def test_aggregator_avg(self):
""" In some reports, some columns can be empty.
Say a model "event", with a field "rating_ids" (relation) and a field "avg_rating" (float related).
If an event has no rating, it would make sense that its "avg_rating" is False rather than 0.
In this case, the event shouldn't be taken into account in the cohort average.
"""
self.patch(self.WebCohortSimpleModel._fields['revenue'], 'aggregator', 'avg')
result = self.WebCohortSimpleModel.get_cohort_data(
'date_start', 'date_stop', 'revenue', 'week', [], 'retention', 'forward'
)
self.assertFalse(
any(
column['percentage'] < 0
for row in result['rows']
for column in row['columns']
),
'All percentages should be positive',
)
class TestCohortBackward(TestCohortCommon):
def setUp(self):
super().setUp()
# activate an extra lang that uses ISO weeks
self.env['res.lang']._activate_lang('en_GB')
start_date = START_DATE
end_date = start_date + datetime.timedelta(days=7) #Start in the future
data_list = []
for i in range(0,NB_START_DAY): #Start date on 20 days
for j in range(0,NB_END_DAY):
data = {
'name': "[%s:%s]" % (i, j),
'type_id': self.type_ids[int(TYPE_SIZE * j / NB_END_DAY)],
'datetime_start': start_date,
'datetime_stop': end_date,
'revenue': j * 10,
}
data_list.append(data)
#Create record with datetime_stop empty
data = {
'name': "[%s:%s] No Stop" % (i, j),
'type_id': self.type_ids[int(TYPE_SIZE * j / NB_END_DAY)],
'datetime_start': start_date,
'datetime_stop': False,
'revenue': j * 10,
}
data_list.append(data)
end_date = end_date - datetime.timedelta(days=3)
start_date = start_date + datetime.timedelta(days=5)
end_date = start_date + datetime.timedelta(days=7)
self.WebCohortSimpleModel.create(data_list)
def test_backward(self):
#Test interval
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'year', [], 'retention', 'backward')['rows']
self.assertEqual(len(result), 2)
self.assertEqual(result[0]['columns'][0]['percentage'], 100.0)
self.assertEqual(result[0]['columns'][-1]['percentage'], 51)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'month', [], 'retention', 'backward')['rows']
self.assertEqual(len(result), 3)
self.assertEqual(result[0]['columns'][0]['percentage'], 100)
self.assertEqual(result[0]['columns'][-2]['percentage'], 63.3)
self.assertEqual(result[0]['columns'][-1]['percentage'], 51)
# with ISO week
result = self.WebCohortSimpleModel.with_context(lang='en_GB').get_cohort_data(
"datetime_start", "datetime_stop", '__count', 'week', [], 'retention', 'backward')['rows']
self.assertEqual(len(result), 11)
self.assertEqual(result[0]['columns'][0]['percentage'], 100)
self.assertEqual(result[0]['columns'][5]['percentage'], 93.3)
self.assertEqual(result[0]['columns'][-2]['percentage'], 58.3)
self.assertEqual(result[0]['columns'][-1]['percentage'], 53.3)
# with en_US week
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'week', [], 'retention', 'backward')['rows']
self.assertEqual(len(result), 11)
self.assertEqual(result[0]['columns'][0]['percentage'], 100)
self.assertEqual(result[0]['columns'][5]['percentage'], 93.3)
self.assertEqual(result[0]['columns'][-2]['percentage'], 58.3)
self.assertEqual(result[0]['columns'][-1]['percentage'], 55)
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'day', [], 'retention', 'backward')['rows']
self.assertEqual(len(result), NB_START_DAY)
self.assertEqual(result[0]['columns'][0]['percentage'], 63.3)
self.assertEqual(result[0]['columns'][-2]['percentage'], 55)
self.assertEqual(result[0]['columns'][-1]['percentage'], 55)
#Test measure
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'revenue', 'week', [], 'retention', 'backward')['rows']
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'type_id', 'week', [], 'retention', 'backward')['rows']
#There is 8 type so value should be 8
self.assertEqual(result[0]['value'], TYPE_SIZE)
#Test Churn mode
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'__count', 'month', [], 'churn', 'backward')['rows']
self.assertEqual(result[0]['columns'][0]['percentage'], 100 - 100)
self.assertEqual(result[0]['columns'][-2]['percentage'], 100 - 63.3)
self.assertEqual(result[0]['columns'][-1]['percentage'], 100 - 51)
class TestCohortEmptyFuturBackward(TestCohortCommon):
def setUp(self):
super().setUp()
start_date = START_DATE
end_date = start_date - datetime.timedelta(days=10)
data_list = []
for j in range(0, 5):
data = {
'name': "[%s] backward" % (j),
'type_id': self.type_ids[int(TYPE_SIZE * j / NB_END_DAY)],
'datetime_start': start_date,
'datetime_stop': end_date,
'revenue': j * 10,
}
data_list.append(data)
end_date = end_date + datetime.timedelta(days=1)
self.WebCohortSimpleModel.create(data_list)
def test_empty_backward(self):
"""
Test when there is no data in the row 0 and in the future
"""
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'revenue', 'day', [], 'retention', 'backward')['rows']
self.assertEqual(result[0]['columns'][0]['value'], 100)
self.assertEqual(result[0]['columns'][-1]['value'], 0)
class TestCohortEmpty(TestCohortCommon):
def test_empty_backward(self):
"""
Test that view doesn't crash when there is no data
"""
result = self.WebCohortSimpleModel.get_cohort_data("datetime_start", "datetime_stop",
'revenue', 'day', [], 'retention', 'backward')['rows']
self.assertEqual(result, [])