mediawiki-extensions-AbuseF.../tests/phpunit/AbuseFilterRowsAndFiltersTestTrait.php
STran ca23e9f06b Convert af_hidden into a bitmask
Protected variables will cause the filter using them to become
protected as well. `af_hidden` can be used to track this flag,
as it is a TINYINT and can be converted into a bitmask with no
schema changes.

This is not a backwards-compatible change, as now all checks must
check the `hidden` flag specifically or otherwise will be cast to
true if any flag is set.

To support this change:
- "hidden" is considered a flag set in the `af_hidden`. This is a
  change in concept with no need for updates to the column values,
  as there is currently only one flag in the bitmask.
- `Flag`s store the bitmask as well as the state of single flags
  and can return either.
- Any checks against the `af_hidden` value no longer check a
  boolean value and instead now check the `hidden` flag value.

Bug: T363906
Change-Id: I358205cb1119cf1e4004892c37e36e0c0a864f37
2024-05-28 00:59:08 -07:00

233 lines
5.2 KiB
PHP

<?php
use MediaWiki\Extension\AbuseFilter\Filter\ExistingFilter;
use MediaWiki\Extension\AbuseFilter\Filter\Flags;
use MediaWiki\Extension\AbuseFilter\Filter\LastEditInfo;
use MediaWiki\Extension\AbuseFilter\Filter\Specs;
/**
* This trait contains some Filter <-> db_row correspondences, and can be used to avoid long test
* methods.
*/
trait AbuseFilterRowsAndFiltersTestTrait {
/**
* @return array[]
*/
public function getRowsAndFilters(): array {
static $ret = null;
if ( $ret !== null ) {
return $ret;
}
$rows = [
'no actions' => (object)[
'af_id' => 42,
'af_pattern' => 'false',
'af_user' => 1,
'af_user_text' => 'FilterTester',
'af_actor' => 1,
'af_timestamp' => '20190826000000',
'af_enabled' => 1,
'af_comments' => '',
'af_public_comments' => 'Mock filter',
'af_hidden' => Flags::FILTER_PUBLIC,
'af_hit_count' => 0,
'af_throttled' => 0,
'af_deleted' => 0,
'af_actions' => '',
'af_global' => 0,
'af_group' => 'default'
],
'with actions' => (object)[
'af_id' => 163,
'af_pattern' => 'false',
'af_user' => 1,
'af_user_text' => 'FilterTester',
'af_actor' => 1,
'af_timestamp' => '20190826000000',
'af_enabled' => 1,
'af_comments' => '',
'af_public_comments' => 'Mock filter',
'af_hidden' => Flags::FILTER_HIDDEN,
'af_hit_count' => 0,
'af_throttled' => 1,
'af_deleted' => 0,
'af_actions' => 'disallow,blockautopromote',
'af_global' => 0,
'af_group' => 'default'
]
];
foreach ( $rows as $name => $row ) {
$actionKeys = $row->af_actions ? explode( ',', $row->af_actions ) : [];
$filter = new ExistingFilter(
new Specs(
$row->af_pattern,
$row->af_comments,
$row->af_public_comments,
$actionKeys,
$row->af_group
),
new Flags(
(bool)$row->af_enabled,
(bool)$row->af_deleted,
(int)$row->af_hidden,
(bool)$row->af_global
),
array_fill_keys( $actionKeys, [] ),
new LastEditInfo(
$row->af_user,
$row->af_user_text,
$row->af_timestamp
),
$row->af_id,
$row->af_hit_count,
$row->af_throttled
);
$ret[$name] = [
'row' => $row,
'actions' => $this->getRowsForActions( $row->af_id, $actionKeys ),
'filter' => $filter
];
}
// Add special cases that cannot be generalized above
$ret = array_merge( $ret, [
'null comments and name' => [
'row' => (object)[
'af_id' => 333,
'af_pattern' => 'false',
'af_user' => 1,
'af_user_text' => 'FilterTester',
'af_actor' => 1,
'af_timestamp' => '20190826000000',
'af_enabled' => 1,
'af_comments' => null,
'af_public_comments' => null,
'af_hidden' => Flags::FILTER_HIDDEN,
'af_hit_count' => 100,
'af_throttled' => 1,
'af_deleted' => 0,
'af_actions' => 'warn',
'af_global' => 0,
'af_group' => 'default'
],
'actions' => $this->getRowsForActions( 333, [ 'warn' ] ),
'filter' => new ExistingFilter(
new Specs(
'false',
'',
'',
[ 'warn' ],
'default'
),
new Flags( true, false, true, false ),
[ 'warn' => [] ],
new LastEditInfo(
1,
'FilterTester',
'20190826000000'
),
333,
100,
1
)
],
'no hitcount and throttled' => [
'row' => (object)[
'af_id' => 1000,
'af_pattern' => '"foo"',
'af_user' => 1,
'af_user_text' => 'FilterTester',
'af_actor' => 1,
'af_timestamp' => '20190826000000',
'af_enabled' => 0,
'af_comments' => 'foo',
'af_public_comments' => 'bar',
'af_hidden' => Flags::FILTER_HIDDEN,
'af_deleted' => 1,
'af_actions' => '',
'af_global' => 1,
'af_group' => 'default'
],
'actions' => [],
'filter' => new ExistingFilter(
new Specs(
'"foo"',
'foo',
'bar',
[],
'default'
),
new Flags( false, true, true, true ),
[],
new LastEditInfo(
1,
'FilterTester',
'20190826000000'
),
1000
)
],
'pattern to trim' => [
'row' => (object)[
'af_id' => 1000,
'af_pattern' => "\n\t 0 \t\n",
'af_user' => 1,
'af_user_text' => 'FilterTester',
'af_actor' => 1,
'af_timestamp' => '20190826000000',
'af_enabled' => 0,
'af_comments' => 'foo',
'af_public_comments' => 'bar',
'af_hidden' => Flags::FILTER_HIDDEN,
'af_hit_count' => 163,
'af_throttled' => 1,
'af_deleted' => 1,
'af_actions' => '',
'af_global' => 1,
'af_group' => 'default'
],
'actions' => [],
'filter' => new ExistingFilter(
new Specs(
'0',
'foo',
'bar',
[],
'default'
),
new Flags( false, true, true, true ),
[],
new LastEditInfo(
1,
'FilterTester',
'20190826000000'
),
1000,
163,
1
)
],
] );
return $ret;
}
/**
* @param int $id
* @param string[] $actions
* @return stdClass[]
*/
private function getRowsForActions( int $id, array $actions ): array {
$ret = [];
foreach ( $actions as $action ) {
$ret[] = (object)[
'afa_filter' => $id,
'afa_consequence' => $action,
'afa_parameters' => ''
];
}
return $ret;
}
}