Initial commit: OCA Ai packages (4 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:05 +02:00
commit 0adb4b78b1
170 changed files with 12385 additions and 0 deletions

View file

@ -0,0 +1,36 @@
/** @odoo-module **/
// ensure mail mock server is loaded first.
import "@mail/../tests/helpers/mock_server";
import {MockServer} from "@web/../tests/helpers/mock_server";
import {patch} from "@web/core/utils/patch";
patch(MockServer.prototype, "ai_oca_bridge", {
async _performRPC(route, args) {
if (args.model === "ai.bridge" && args.method === "execute_ai_bridge") {
const record = this.models["ai.bridge"].records.filter(
(record) => record.id === args.args[0][0]
);
if (record && record[0].result_type === "action") {
return {
action: {
type: "ir.actions.act_window",
res_model: "res.partner",
views: [[false, "tree"]],
},
};
}
return {
notification: {
body: "Mocked AI Bridge Response",
args: {
type: "info",
title: "AI Bridge Notification",
},
},
};
}
return this._super(...arguments);
},
});

View file

@ -0,0 +1,29 @@
/** @odoo-module **/
import {
addModelNamesToFetch,
insertModelFields,
insertRecords,
} from "@bus/../tests/helpers/model_definitions_helpers";
addModelNamesToFetch(["ai.bridge"]);
insertModelFields("res.partner", {
ai_bridge_info: {default: [], type: "json"},
});
insertModelFields("ai.bridge", {
result_type: {
default: "none",
type: "selection",
selection: [
["none", "None"],
["action", "Action"],
["notification", "Notification"],
],
},
name: {string: "Name", type: "char"},
});
insertRecords("ai.bridge", [
{id: 1, name: "Test AI Bridge", result_type: "none"},
{id: 2, name: "Test AI Bridge Action", result_type: "action"},
]);

View file

@ -0,0 +1,98 @@
/** @odoo-module */
/* global QUnit */
/*
Copyright 2025 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
*/
import {start, startServer} from "@mail/../tests/helpers/test_utils";
QUnit.module("ai_oca_bridge");
QUnit.test("AI Notification", async function (assert) {
const pyEnv = await startServer();
const resPartnerId1 = pyEnv["res.partner"].create({
ai_bridge_info: [
{name: "AI 1", id: 1, description: "test1 description"},
{name: "AI 2", id: 2},
],
});
const views = {
"res.partner,false,form": `<form>
<field name="ai_bridge_info" />
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="message_ids"/>
</div>
</form>`,
};
const {click, openView} = await start({serverData: {views}});
await openView({
res_id: resPartnerId1,
res_model: "res.partner",
views: [[false, "form"]],
});
await assert.strictEqual(
document.querySelectorAll(`.o_ChatterTopbar_AIButton .ai_button_selection`)
.length,
1,
"should have an AI button"
);
await click(".o_ChatterTopbar_AIButton .ai_button_selection");
assert.strictEqual(
document.querySelectorAll(`.o_ChatterTopbar_AIItem`).length,
2,
"should have 2 AI Items"
);
await click(document.querySelectorAll(".o_ChatterTopbar_AIItem")[0]);
assert.strictEqual(
document.querySelectorAll(`.o_notification_manager .o_notification`).length,
1,
"should have 1 Notification after clicking on AI Item"
);
});
QUnit.test("AI Action", async function (assert) {
const pyEnv = await startServer();
const resPartnerId1 = pyEnv["res.partner"].create({
ai_bridge_info: [
{name: "AI 1", id: 1, description: "test1 description"},
{name: "AI 2", id: 2},
],
});
const views = {
"res.partner,false,form": `<form>
<field name="ai_bridge_info" />
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="message_ids"/>
</div>
</form>`,
"res.partner,false,tree": `<tree>
<field name="name"/>
<field name="active"/>
</tree>`,
};
const {click, openView} = await start({serverData: {views}});
await openView({
res_id: resPartnerId1,
res_model: "res.partner",
views: [[false, "form"]],
});
await assert.strictEqual(
document.querySelectorAll(`.o_ChatterTopbar_AIButton .ai_button_selection`)
.length,
1,
"should have an AI button"
);
await click(".o_ChatterTopbar_AIButton .ai_button_selection");
assert.strictEqual(
document.querySelectorAll(`.o_ChatterTopbar_AIItem`).length,
2,
"should have 2 AI Items"
);
await click(document.querySelectorAll(".o_ChatterTopbar_AIItem")[1]);
assert.strictEqual(
document.querySelectorAll(`.o_list_view`).length,
1,
"should have 1 List View after clicking on AI Item with action"
);
});