[FIX] web: Make sample server tests deterministic
Before this commit, there were a few tests in the "sample server" suite that asserted that every group resulting of a "read_group" would contain at least one record, while there was actually a slight chance of it not happening. Now, the sample server used in the tests has been rendered deterministic and these kind of issues are completely avoided. closes odoo/odoo#54164 X-original-commit: a6d32ff46558b68ce3f19458f29c311ee5c658fd Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
This commit is contained in:
@@ -198,7 +198,7 @@ odoo.define('web.SampleServer', function (require) {
|
||||
const field = this.data[modelName].fields[fieldName];
|
||||
switch (field.type) {
|
||||
case "boolean":
|
||||
return fieldName === 'active' ? true : Math.random() < 0.5;
|
||||
return fieldName === 'active' ? true : this._getRandomBool();
|
||||
case "char":
|
||||
case "text":
|
||||
if (["display_name", "name"].includes(fieldName)) {
|
||||
@@ -227,23 +227,22 @@ odoo.define('web.SampleServer', function (require) {
|
||||
return false;
|
||||
case "date":
|
||||
case "datetime": {
|
||||
const delta = Math.floor((Math.random() - Math.random()) * SampleServer.DATE_DELTA);
|
||||
const date = new moment().add(delta, "hour").format(
|
||||
field.type === "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss"
|
||||
);
|
||||
return date;
|
||||
const format = field.type === "date" ?
|
||||
"YYYY-MM-DD" :
|
||||
"YYYY-MM-DD HH:mm:ss";
|
||||
return this._getRandomDate(format);
|
||||
}
|
||||
case "float":
|
||||
return Math.random() * SampleServer.MAX_FLOAT;
|
||||
return this._getRandomFloat(SampleServer.MAX_FLOAT);
|
||||
case "integer": {
|
||||
let max = SampleServer.MAX_INTEGER;
|
||||
if (fieldName.includes('color')) {
|
||||
max = Math.random() < 0.5 ? SampleServer.MAX_COLOR_INT : 0;
|
||||
max = this._getRandomBool() ? SampleServer.MAX_COLOR_INT : 0;
|
||||
}
|
||||
return Math.floor(Math.random() * max);
|
||||
return this._getRandomInt(max);
|
||||
}
|
||||
case "monetary":
|
||||
return Math.floor(Math.random() * SampleServer.MAX_MONETARY);
|
||||
return this._getRandomInt(SampleServer.MAX_MONETARY);
|
||||
case "many2one":
|
||||
if (field.relation === 'res.currency') {
|
||||
return session.company_currency_id;
|
||||
@@ -256,8 +255,7 @@ odoo.define('web.SampleServer', function (require) {
|
||||
}
|
||||
case "selection": {
|
||||
if (field.selection.length > 0) {
|
||||
const index = Math.floor(Math.random() * field.selection.length);
|
||||
return field.selection[index][0];
|
||||
return this._getRandomArrayEl(field.selection)[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -267,7 +265,55 @@ odoo.define('web.SampleServer', function (require) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random id in the range of ids generated for sub models.
|
||||
* @private
|
||||
* @param {any[]} array
|
||||
* @returns {any}
|
||||
*/
|
||||
_getRandomArrayEl(array) {
|
||||
return array[Math.floor(Math.random() * array.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_getRandomBool() {
|
||||
return Math.random() < 0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string} format
|
||||
* @returns {moment}
|
||||
*/
|
||||
_getRandomDate(format) {
|
||||
const delta = Math.floor(
|
||||
(Math.random() - Math.random()) * SampleServer.DATE_DELTA
|
||||
);
|
||||
return new moment()
|
||||
.add(delta, "hour")
|
||||
.format(format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} max
|
||||
* @returns {number} float in [O, max[
|
||||
*/
|
||||
_getRandomFloat(max) {
|
||||
return Math.random() * max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} max
|
||||
* @returns {number} int in [0, max[
|
||||
*/
|
||||
_getRandomInt(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {number} id in [1, SUB_RECORDSET_SIZE]
|
||||
*/
|
||||
|
||||
@@ -8,9 +8,31 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
const {
|
||||
MAIN_RECORDSET_SIZE, SEARCH_READ_LIMIT, // Limits
|
||||
SAMPLE_COUNTRIES, SAMPLE_PEOPLE, SAMPLE_TEXTS, // Text values
|
||||
MAX_COLOR_INT, MAX_FLOAT, MAX_INTEGER, MAX_MONETARY // Number values
|
||||
MAX_COLOR_INT, MAX_FLOAT, MAX_INTEGER, MAX_MONETARY, // Number values
|
||||
SUB_RECORDSET_SIZE, // Records sise
|
||||
} = SampleServer;
|
||||
|
||||
/**
|
||||
* Transforms random results into deterministic ones.
|
||||
*/
|
||||
class DeterministicSampleServer extends SampleServer {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.arrayElCpt = 0;
|
||||
this.boolCpt = 0;
|
||||
this.subRecordIdCpt = 0;
|
||||
}
|
||||
_getRandomArrayEl(array) {
|
||||
return array[this.arrayElCpt++ % array.length];
|
||||
}
|
||||
_getRandomBool() {
|
||||
return Boolean(this.boolCpt++ % 2);
|
||||
}
|
||||
_getRandomSubRecordId() {
|
||||
return (this.subRecordIdCpt++ % SUB_RECORDSET_SIZE) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
QUnit.module("Sample Server", {
|
||||
beforeEach() {
|
||||
this.fields = {
|
||||
@@ -62,7 +84,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
const allFieldNames = Object.keys(this.fields['res.users']);
|
||||
const server = new SampleServer('res.users', this.fields['res.users']);
|
||||
const server = new DeterministicSampleServer('res.users', this.fields['res.users']);
|
||||
const { records } = await server.mockRpc({
|
||||
method: '/web/dataset/search_read',
|
||||
model: 'res.users',
|
||||
@@ -127,12 +149,12 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
assert.strictEqual(typeof rec.manager_id[0], 'number');
|
||||
assert.ok(SAMPLE_PEOPLE.includes(rec.manager_id[1]));
|
||||
|
||||
assert.ok([1, 2].includes(rec.managed_ids.length));
|
||||
assert.strictEqual(rec.managed_ids.length, 2);
|
||||
assert.ok(rec.managed_ids.every(
|
||||
(id) => typeof id === 'number')
|
||||
);
|
||||
|
||||
assert.ok([1, 2].includes(rec.tag_ids.length));
|
||||
assert.strictEqual(rec.tag_ids.length, 2);
|
||||
assert.ok(rec.tag_ids.every(
|
||||
(id) => typeof id === 'number')
|
||||
);
|
||||
@@ -143,7 +165,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Sample data: country type", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('res.country', this.fields['res.country']);
|
||||
const server = new DeterministicSampleServer('res.country', this.fields['res.country']);
|
||||
const { records } = await server.mockRpc({
|
||||
method: '/web/dataset/search_read',
|
||||
model: 'res.country',
|
||||
@@ -156,7 +178,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Sample data: any type", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const { records } = await server.mockRpc({
|
||||
method: '/web/dataset/search_read',
|
||||
@@ -172,7 +194,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'search_read' RPC: valid field names", async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: '/web/dataset/search_read',
|
||||
@@ -193,7 +215,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'search_read' RPC: invalid field names", async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: '/web/dataset/search_read',
|
||||
@@ -214,7 +236,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'web_read_group' RPC: no group", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
server.setExistingGroups([]);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
@@ -227,9 +249,9 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
QUnit.test("Send 'web_read_group' RPC: 2 groups", async function (assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(5);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
const existingGroups = [
|
||||
{ profession: 'gardener', profession_count: 0 },
|
||||
{ profession: 'adventurer', profession_count: 0 },
|
||||
@@ -246,9 +268,10 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
assert.strictEqual(result.length, 2);
|
||||
assert.strictEqual(result.groups.length, 2);
|
||||
|
||||
const professions = result.groups.map((g) => g.profession);
|
||||
assert.ok(professions.includes("gardener"));
|
||||
assert.ok(professions.includes("adventurer"));
|
||||
assert.deepEqual(
|
||||
result.groups.map((g) => g.profession),
|
||||
["gardener", "adventurer"]
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
result.groups.reduce((acc, g) => acc + g.profession_count, 0),
|
||||
@@ -260,9 +283,9 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
QUnit.test("Send 'web_read_group' RPC: all groups", async function (assert) {
|
||||
assert.expect(7);
|
||||
assert.expect(5);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
const existingGroups = [
|
||||
{ profession: 'gardener', profession_count: 0 },
|
||||
{ profession: 'brewer', profession_count: 0 },
|
||||
@@ -280,10 +303,10 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
assert.strictEqual(result.length, 3);
|
||||
assert.strictEqual(result.groups.length, 3);
|
||||
|
||||
const professions = result.groups.map((g) => g.profession);
|
||||
assert.ok(professions.includes("gardener"));
|
||||
assert.ok(professions.includes("brewer"));
|
||||
assert.ok(professions.includes("adventurer"));
|
||||
assert.deepEqual(
|
||||
result.groups.map((g) => g.profession),
|
||||
["gardener", "brewer", "adventurer"]
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
result.groups.reduce((acc, g) => acc + g.profession_count, 0),
|
||||
@@ -297,7 +320,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read_group' RPC: no group", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read_group',
|
||||
@@ -313,9 +336,9 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
QUnit.test("Send 'read_group' RPC: groupBy", async function (assert) {
|
||||
assert.expect(5);
|
||||
assert.expect(3);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read_group',
|
||||
@@ -325,12 +348,10 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
assert.strictEqual(result.length, 3);
|
||||
|
||||
const professions = result.map((g) => g.profession);
|
||||
assert.ok(professions.includes("gardener"));
|
||||
assert.ok(professions.includes("brewer"));
|
||||
assert.ok(professions.includes("adventurer"));
|
||||
|
||||
assert.deepEqual(
|
||||
result.map((g) => g.profession),
|
||||
["gardener", "brewer", "adventurer"]
|
||||
);
|
||||
assert.strictEqual(
|
||||
result.reduce((acc, g) => acc + g.profession_count, 0),
|
||||
MAIN_RECORDSET_SIZE,
|
||||
@@ -338,9 +359,9 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
QUnit.test("Send 'read_group' RPC: groupBy and field", async function (assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(4);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read_group',
|
||||
@@ -350,17 +371,14 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
});
|
||||
|
||||
assert.strictEqual(result.length, 3);
|
||||
|
||||
const professions = result.map((g) => g.profession);
|
||||
assert.ok(professions.includes("gardener"));
|
||||
assert.ok(professions.includes("brewer"));
|
||||
assert.ok(professions.includes("adventurer"));
|
||||
|
||||
assert.deepEqual(
|
||||
result.map((g) => g.profession),
|
||||
["gardener", "brewer", "adventurer"]
|
||||
);
|
||||
assert.strictEqual(
|
||||
result.reduce((acc, g) => acc + g.profession_count, 0),
|
||||
MAIN_RECORDSET_SIZE,
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
result.reduce((acc, g) => acc + g.age, 0),
|
||||
server.data.hobbit.records.reduce((acc, g) => acc + g.age, 0)
|
||||
@@ -370,7 +388,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read_group' RPC: multiple groupBys and lazy", async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read_group',
|
||||
@@ -386,7 +404,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read_group' RPC: multiple groupBys and not lazy", async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read_group',
|
||||
@@ -403,7 +421,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read' RPC: no id", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read',
|
||||
@@ -419,7 +437,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read' RPC: one id", async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const result = await server.mockRpc({
|
||||
method: 'read',
|
||||
@@ -440,7 +458,7 @@ odoo.define('web.sample_server_tests', function (require) {
|
||||
QUnit.test("Send 'read' RPC: more than all available ids", async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const server = new SampleServer('hobbit', this.fields.hobbit);
|
||||
const server = new DeterministicSampleServer('hobbit', this.fields.hobbit);
|
||||
|
||||
const amount = MAIN_RECORDSET_SIZE + 3;
|
||||
const ids = new Array(amount).fill().map((_, i) => i + 1);
|
||||
|
||||
Reference in New Issue
Block a user