Files
Christopher PoileandClaude Opus 4.7 03f2eaaa0b [MM-68400] Four plugin hooks and ChannelGuard enforcement (#36152)
* allow workflow_dispatch trigger for Server CI (for plugins CI)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [MM-68402] MBE Phase 2: declare four generic plugin hooks (#36291)

* new hooks-only phase 2

* remove ChannelWillBeMoved

* remove RecapWillBeProcessed and MessageWillBeRewrittenByAI

Drop the AI/recap hooks from the new-hook surface; AI-LLM paths
remain uncovered in tech preview and are documented as residuals.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [MM-68403] MBE Phase 3: ChannelGuards primitive (storage + cache + plugin API) (#36365)

* phase 3

* phase 3: register ChannelGuard mock in test setup helper

NewChannels' startup-time call to reloadGuardCache invokes
s.ChannelGuard().GetAll(); without an expectation on the mock store,
every test that sets up the server with GetMockStoreForSetupFunctions
panics during init.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* phase 3: register ChannelGuard mock in retrylayer test

retrylayer.New walks every store getter to wrap it; without the mock
expectation on ChannelGuard, TestRetry panics during layer construction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* use rctx properly in the store methods

* phase 3: match rctx arg in testlib ChannelGuard mock

GetAll now takes request.CTX, so the testify expectation must include
mock.Anything; otherwise the call panics under the mocked store.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* phase 3: set api.ctx in TestChannelGuardLowercaseNormalization

The test constructs PluginAPI directly without a ctx, which used to
work when App.RegisterChannelGuard built its own EmptyContext. Now
that the App methods take rctx from the caller, the nil ctx panics
inside RequestContextWithMaster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [MM-68404] MBE Phase 4: App-layer plugin hook wiring (#36407)

* phase 4

* Fix nil rctx in TestChannelGuardLowercaseNormalization

The PluginAPI struct literal was missing ctx: rctx after a refactor
moved the rctx declaration below the struct construction, leaving
api.ctx as nil. This caused a nil pointer dereference in reloadGuardCache
when RegisterChannelGuard called store.RequestContextWithMaster(nil).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* Remove ChannelWillBeMoved hook call from MoveChannel (phase 4)

The hook and its ID were removed from mbe-phase-2 but the call site in
MoveChannel and its i18n string were not cleaned up during the rebase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* remove channel will be moved test

* Remove RecapWillBeProcessed and MessageWillBeRewrittenByAI hook calls (phase 4)

The hooks and their IDs were removed from mbe-phase-2 but the call sites
in ProcessRecapChannel and RewriteMessage, their i18n strings, and their
tests were not cleaned up during the rebase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Revert channel_id plumbing on rewrite endpoint (phase 4)

The channel_id field on RewriteRequest was added in phase 4 to feed the
synthetic post passed to MessageWillBeRewrittenByAI. With that hook
removed from mbe-phase-2, channel_id has no consumer; revert the field,
the api4 validation, the app.RewriteMessage parameter, and the
corresponding webapp client + hook plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [MM-68555] MBE Phase 5: Channel-guard enforcement + two-phase dispatch (#36473)

* phase 5

* Bake plugin counter-file paths into source instead of env vars

t.Setenv panics when an ancestor test calls t.Parallel, so the two
channel-guard tests broke under ENABLE_FULLY_PARALLEL_TESTS in CI.
Build each plugin source per-subtest with its temp file path embedded
as a Go literal — same pattern as TestPluginUploadsAPI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Remove guarded helpers and tests for dropped hooks (phase 5)

The runGuardedRecapWillBeProcessed and runGuardedMessageWillBeRewrittenByAI
helpers were never wired (their app-layer call sites were already removed
in the phase-4 cleanup), and the corresponding sub-tests across panic /
allow / reject / partial plugins reference hooks that no longer exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [MM-68405] MBE Phase 6: fire MessagesWillBeConsumed on the edit path (#36475)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* rebase onto master

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 18:16:05 +00:00

481 lines
11 KiB
Go

// Code generated by mockery v2.53.4. DO NOT EDIT.
// Regenerate this file using `make plugin-mocks`.
package plugintest
import (
driver "database/sql/driver"
plugin "github.com/mattermost/mattermost/server/public/plugin"
mock "github.com/stretchr/testify/mock"
)
// Driver is an autogenerated mock type for the Driver type
type Driver struct {
mock.Mock
}
// Conn provides a mock function with given fields: isMaster
func (_m *Driver) Conn(isMaster bool) (string, error) {
ret := _m.Called(isMaster)
if len(ret) == 0 {
panic("no return value specified for Conn")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(bool) (string, error)); ok {
return rf(isMaster)
}
if rf, ok := ret.Get(0).(func(bool) string); ok {
r0 = rf(isMaster)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(bool) error); ok {
r1 = rf(isMaster)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ConnClose provides a mock function with given fields: connID
func (_m *Driver) ConnClose(connID string) error {
ret := _m.Called(connID)
if len(ret) == 0 {
panic("no return value specified for ConnClose")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(connID)
} else {
r0 = ret.Error(0)
}
return r0
}
// ConnExec provides a mock function with given fields: connID, q, args
func (_m *Driver) ConnExec(connID string, q string, args []driver.NamedValue) (plugin.ResultContainer, error) {
ret := _m.Called(connID, q, args)
if len(ret) == 0 {
panic("no return value specified for ConnExec")
}
var r0 plugin.ResultContainer
var r1 error
if rf, ok := ret.Get(0).(func(string, string, []driver.NamedValue) (plugin.ResultContainer, error)); ok {
return rf(connID, q, args)
}
if rf, ok := ret.Get(0).(func(string, string, []driver.NamedValue) plugin.ResultContainer); ok {
r0 = rf(connID, q, args)
} else {
r0 = ret.Get(0).(plugin.ResultContainer)
}
if rf, ok := ret.Get(1).(func(string, string, []driver.NamedValue) error); ok {
r1 = rf(connID, q, args)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ConnPing provides a mock function with given fields: connID
func (_m *Driver) ConnPing(connID string) error {
ret := _m.Called(connID)
if len(ret) == 0 {
panic("no return value specified for ConnPing")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(connID)
} else {
r0 = ret.Error(0)
}
return r0
}
// ConnQuery provides a mock function with given fields: connID, q, args
func (_m *Driver) ConnQuery(connID string, q string, args []driver.NamedValue) (string, error) {
ret := _m.Called(connID, q, args)
if len(ret) == 0 {
panic("no return value specified for ConnQuery")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string, string, []driver.NamedValue) (string, error)); ok {
return rf(connID, q, args)
}
if rf, ok := ret.Get(0).(func(string, string, []driver.NamedValue) string); ok {
r0 = rf(connID, q, args)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string, string, []driver.NamedValue) error); ok {
r1 = rf(connID, q, args)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// RowsClose provides a mock function with given fields: rowsID
func (_m *Driver) RowsClose(rowsID string) error {
ret := _m.Called(rowsID)
if len(ret) == 0 {
panic("no return value specified for RowsClose")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(rowsID)
} else {
r0 = ret.Error(0)
}
return r0
}
// RowsColumnTypeDatabaseTypeName provides a mock function with given fields: rowsID, index
func (_m *Driver) RowsColumnTypeDatabaseTypeName(rowsID string, index int) string {
ret := _m.Called(rowsID, index)
if len(ret) == 0 {
panic("no return value specified for RowsColumnTypeDatabaseTypeName")
}
var r0 string
if rf, ok := ret.Get(0).(func(string, int) string); ok {
r0 = rf(rowsID, index)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// RowsColumnTypePrecisionScale provides a mock function with given fields: rowsID, index
func (_m *Driver) RowsColumnTypePrecisionScale(rowsID string, index int) (int64, int64, bool) {
ret := _m.Called(rowsID, index)
if len(ret) == 0 {
panic("no return value specified for RowsColumnTypePrecisionScale")
}
var r0 int64
var r1 int64
var r2 bool
if rf, ok := ret.Get(0).(func(string, int) (int64, int64, bool)); ok {
return rf(rowsID, index)
}
if rf, ok := ret.Get(0).(func(string, int) int64); ok {
r0 = rf(rowsID, index)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(string, int) int64); ok {
r1 = rf(rowsID, index)
} else {
r1 = ret.Get(1).(int64)
}
if rf, ok := ret.Get(2).(func(string, int) bool); ok {
r2 = rf(rowsID, index)
} else {
r2 = ret.Get(2).(bool)
}
return r0, r1, r2
}
// RowsColumns provides a mock function with given fields: rowsID
func (_m *Driver) RowsColumns(rowsID string) []string {
ret := _m.Called(rowsID)
if len(ret) == 0 {
panic("no return value specified for RowsColumns")
}
var r0 []string
if rf, ok := ret.Get(0).(func(string) []string); ok {
r0 = rf(rowsID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
return r0
}
// RowsHasNextResultSet provides a mock function with given fields: rowsID
func (_m *Driver) RowsHasNextResultSet(rowsID string) bool {
ret := _m.Called(rowsID)
if len(ret) == 0 {
panic("no return value specified for RowsHasNextResultSet")
}
var r0 bool
if rf, ok := ret.Get(0).(func(string) bool); ok {
r0 = rf(rowsID)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// RowsNext provides a mock function with given fields: rowsID, dest
func (_m *Driver) RowsNext(rowsID string, dest []driver.Value) error {
ret := _m.Called(rowsID, dest)
if len(ret) == 0 {
panic("no return value specified for RowsNext")
}
var r0 error
if rf, ok := ret.Get(0).(func(string, []driver.Value) error); ok {
r0 = rf(rowsID, dest)
} else {
r0 = ret.Error(0)
}
return r0
}
// RowsNextResultSet provides a mock function with given fields: rowsID
func (_m *Driver) RowsNextResultSet(rowsID string) error {
ret := _m.Called(rowsID)
if len(ret) == 0 {
panic("no return value specified for RowsNextResultSet")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(rowsID)
} else {
r0 = ret.Error(0)
}
return r0
}
// Stmt provides a mock function with given fields: connID, q
func (_m *Driver) Stmt(connID string, q string) (string, error) {
ret := _m.Called(connID, q)
if len(ret) == 0 {
panic("no return value specified for Stmt")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok {
return rf(connID, q)
}
if rf, ok := ret.Get(0).(func(string, string) string); ok {
r0 = rf(connID, q)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(connID, q)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// StmtClose provides a mock function with given fields: stID
func (_m *Driver) StmtClose(stID string) error {
ret := _m.Called(stID)
if len(ret) == 0 {
panic("no return value specified for StmtClose")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(stID)
} else {
r0 = ret.Error(0)
}
return r0
}
// StmtExec provides a mock function with given fields: stID, args
func (_m *Driver) StmtExec(stID string, args []driver.NamedValue) (plugin.ResultContainer, error) {
ret := _m.Called(stID, args)
if len(ret) == 0 {
panic("no return value specified for StmtExec")
}
var r0 plugin.ResultContainer
var r1 error
if rf, ok := ret.Get(0).(func(string, []driver.NamedValue) (plugin.ResultContainer, error)); ok {
return rf(stID, args)
}
if rf, ok := ret.Get(0).(func(string, []driver.NamedValue) plugin.ResultContainer); ok {
r0 = rf(stID, args)
} else {
r0 = ret.Get(0).(plugin.ResultContainer)
}
if rf, ok := ret.Get(1).(func(string, []driver.NamedValue) error); ok {
r1 = rf(stID, args)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// StmtNumInput provides a mock function with given fields: stID
func (_m *Driver) StmtNumInput(stID string) int {
ret := _m.Called(stID)
if len(ret) == 0 {
panic("no return value specified for StmtNumInput")
}
var r0 int
if rf, ok := ret.Get(0).(func(string) int); ok {
r0 = rf(stID)
} else {
r0 = ret.Get(0).(int)
}
return r0
}
// StmtQuery provides a mock function with given fields: stID, args
func (_m *Driver) StmtQuery(stID string, args []driver.NamedValue) (string, error) {
ret := _m.Called(stID, args)
if len(ret) == 0 {
panic("no return value specified for StmtQuery")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string, []driver.NamedValue) (string, error)); ok {
return rf(stID, args)
}
if rf, ok := ret.Get(0).(func(string, []driver.NamedValue) string); ok {
r0 = rf(stID, args)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string, []driver.NamedValue) error); ok {
r1 = rf(stID, args)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Tx provides a mock function with given fields: connID, opts
func (_m *Driver) Tx(connID string, opts driver.TxOptions) (string, error) {
ret := _m.Called(connID, opts)
if len(ret) == 0 {
panic("no return value specified for Tx")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string, driver.TxOptions) (string, error)); ok {
return rf(connID, opts)
}
if rf, ok := ret.Get(0).(func(string, driver.TxOptions) string); ok {
r0 = rf(connID, opts)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string, driver.TxOptions) error); ok {
r1 = rf(connID, opts)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// TxCommit provides a mock function with given fields: txID
func (_m *Driver) TxCommit(txID string) error {
ret := _m.Called(txID)
if len(ret) == 0 {
panic("no return value specified for TxCommit")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(txID)
} else {
r0 = ret.Error(0)
}
return r0
}
// TxRollback provides a mock function with given fields: txID
func (_m *Driver) TxRollback(txID string) error {
ret := _m.Called(txID)
if len(ret) == 0 {
panic("no return value specified for TxRollback")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(txID)
} else {
r0 = ret.Error(0)
}
return r0
}
// NewDriver creates a new instance of Driver. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDriver(t interface {
mock.TestingT
Cleanup(func())
}) *Driver {
mock := &Driver{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}