2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-10-03 15:52:51 +00:00

[Refactor] Notification plugins (#9735)

* Refactor notification concept

- Notifications handled by plugins

* Cleanup

* Only send email if template provided in context

* Logic cleanup

* Fix log_error call

* Refactor error logging

- Ensure plugin slug is correctly attached
- Consistent format
- Logic fixes

* More robust plugin lookup

* Refactor calls to tringger_notification

* Tweak for build stock notification

* Low stock notification refactor

- Actually *use* the notification system
- Fix for email template

* Check stock only when build is issued

* Updated documentation

* Add PluginUserSetting class

- Allows plugins to define per-user settings

* Add API endpoints for PluginUserSetting model

* Placeholder for user-plugin-settings page

* Refactoring frontend code

* Placeholder panel

* Adds user interface for changing user-specific plugin settings

* Tweaks

* Remove old model

* Update documentation

* Playwright tests

* Update API version

* Fix unit test

* Fix removed arg

* Fixes for email notifications

- Track status of sending notifications
- Add helper "activate" method for plugin class
- Update unit tests

* Fix barcode tests

* More unit test fixes

* Test fixes

* Fix for settings models with extra fields

* Enhance unit test

* Remove old test file

* Check for null target_fnc

* Improve DB query efficiency

- Provide a flat list of active keys to plugin.is_active
- Prevents DB fetching (in certain circumstances)
- Add registry.active_plugins() method

* Bump query limit up for test

- In practice, this API endpoint is ~10 queries

* Handle potential errors

* Increase query limit for API test

* Increase query limit for some tests

* Bump API version

* Tweak unit test

* Tweak unit test

* Increased allowed queries

* fix user plugin settings

* Fix for unit test

* Update debug msg

* Tweak API

* Fix endpoint

* Remove "active plugin keys" code

* Restore previous behaviour

* Fix unit tests

* Tweak unit test

* Update src/backend/InvenTree/build/tasks.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/backend/InvenTree/plugin/base/integration/NotificationMixin.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Func updates

* Format

* Add notification settings

* Refactor plugin settings groups

* Fix func type

* Adjust message

* Additional unit tests

* Additional playwright tests

* Additional playwright test

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Oliver
2025-07-26 13:05:59 +10:00
committed by GitHub
parent f862867e2b
commit 1085625af4
60 changed files with 1329 additions and 972 deletions

View File

@@ -2,7 +2,7 @@ import { expect, test } from './baseFixtures.js';
import { apiUrl } from './defaults.js';
import { getRowFromCell, loadTab, navigate } from './helpers.js';
import { doCachedLogin } from './login.js';
import { setSettingState } from './settings.js';
import { setPluginState, setSettingState } from './settings.js';
/**
* Adjust language and color settings
@@ -80,6 +80,97 @@ test('Settings - User theme', async ({ browser }) => {
await page.getByLabel('#228be6').click();
});
test('Settings - User', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'allaccess',
password: 'nolimits',
url: 'settings/user/'
});
await loadTab(page, 'Account');
await page.getByText('Account Details').waitFor();
await page.getByText('Profile Details').waitFor();
await loadTab(page, 'Security');
await page.getByRole('button', { name: 'Single Sign On' }).waitFor();
await page.getByRole('button', { name: 'Access Tokens' }).waitFor();
await loadTab(page, 'Display Options');
await page
.getByText('The navbar position is fixed to the top of the screen')
.waitFor();
await page.getByText('Escape Key Closes Forms').waitFor();
await loadTab(page, 'Search');
await page.getByText('Whole Word Search').waitFor();
await page.getByText('Hide Unavailable Stock Items').waitFor();
await loadTab(page, 'Notifications');
await page
.getByRole('button', { name: 'InvenTree Email Notifications' })
.waitFor();
await loadTab(page, 'Reporting');
await page.getByText('Inline report display').waitFor();
await loadTab(page, 'Plugin Settings');
await page
.getByRole('button', { name: 'InvenTree Email Notifications' })
.waitFor();
});
test('Settings - Global', async ({ browser, request }) => {
const page = await doCachedLogin(browser, {
username: 'steven',
password: 'wizardstaff',
url: 'settings/system/'
});
// Ensure the "slack" notification plugin is enabled
// This is to ensure it is visible in the "notification" settings tab
await setPluginState({
request,
plugin: 'inventree-slack-notification',
state: true
});
await loadTab(page, 'Server');
await loadTab(page, 'Authentication');
await loadTab(page, 'Barcodes');
await loadTab(page, 'Pricing');
await loadTab(page, 'Parts');
await loadTab(page, 'Stock');
await loadTab(page, 'Notifications');
await page
.getByText(
'The settings below are specific to each available notification method'
)
.waitFor();
await page
.getByRole('button', { name: 'InvenTree Slack Notifications' })
.click();
await page.getByText('Slack incoming webhook url').waitFor();
await page
.getByText('URL that is used to send messages to a slack channel')
.waitFor();
await loadTab(page, 'Plugin Settings');
await page
.getByText('The settings below are specific to each available plugin')
.waitFor();
await page
.getByRole('button', { name: 'InvenTree Barcodes Provides' })
.waitFor();
await page
.getByRole('button', { name: 'InvenTree PDF label printer' })
.waitFor();
await page
.getByRole('button', { name: 'InvenTree Slack Notifications' })
.waitFor();
});
test('Settings - Admin', async ({ browser }) => {
// Note here we login with admin access
const page = await doCachedLogin(browser, {