1<?php
2
3namespace MediaWiki\Tests\User;
4
5use MediaWiki\User\UserIdentityValue;
6use MediaWiki\User\UserSelectQueryBuilder;
7use Wikimedia\Rdbms\SelectQueryBuilder;
8
9/**
10 * @group Database
11 * @covers \MediaWiki\User\UserSelectQueryBuilder
12 * @coversDefaultClass \MediaWiki\User\UserSelectQueryBuilder
13 * @package MediaWiki\Tests\User
14 */
15class UserSelectQueryBuilderTest extends ActorStoreTestBase {
16	public function provideFetchUserIdentitiesByNamePrefix() {
17		yield 'nothing found' => [
18			'z_z_Z_Z_z_Z_z_z', // $prefix
19			[ 'limit' => 100 ], // $options
20			[], // $expected
21		];
22		yield 'default parameters' => [
23			'Test', // $prefix
24			[ 'limit' => 100 ], // $options
25			[
26				new UserIdentityValue( 24, 'TestUser' ),
27				new UserIdentityValue( 25, 'TestUser1' ),
28			], // $expected
29		];
30		yield 'limited' => [
31			'Test', // $prefix
32			[ 'limit' => 1 ], // $options
33			[
34				new UserIdentityValue( 24, 'TestUser' ),
35			], // $expected
36		];
37		yield 'sorted' => [
38			'Test', // $prefix
39			[
40				'sort' => UserSelectQueryBuilder::SORT_DESC,
41				'limit' => 100,
42			], // $options
43			[
44				new UserIdentityValue( 25, 'TestUser1' ),
45				new UserIdentityValue( 24, 'TestUser' ),
46			], // $expected
47		];
48	}
49
50	/**
51	 * @dataProvider provideFetchUserIdentitiesByNamePrefix
52	 */
53	public function testFetchUserIdentitiesByNamePrefix( string $prefix, array $options, array $expected ) {
54		$queryBuilder = $this->getStore()
55			->newSelectQueryBuilder()
56			->limit( $options['limit'] )
57			->whereUserNamePrefix( $prefix )
58			->caller( __METHOD__ )
59			->orderByName( $options['sort'] ?? SelectQueryBuilder::SORT_ASC );
60		$actors = iterator_to_array( $queryBuilder->fetchUserIdentities() );
61		$this->assertCount( count( $expected ), $actors );
62		foreach ( $expected as $idx => $expectedActor ) {
63			$this->assertSameActors( $expectedActor, $actors[$idx] );
64		}
65	}
66
67	public function provideFetchUserIdentitiesByUserIds() {
68		yield 'default parameters' => [
69			[ 24, 25 ], // ids
70			[], // $options
71			[
72				new UserIdentityValue( 24, 'TestUser' ),
73				new UserIdentityValue( 25, 'TestUser1' ),
74			], // $expected
75		];
76		yield 'sorted' => [
77			[ 24, 25 ], // ids
78			[ 'sort' => UserSelectQueryBuilder::SORT_DESC ], // $options
79			[
80				new UserIdentityValue( 25, 'TestUser1' ),
81				new UserIdentityValue( 24, 'TestUser' ),
82			], // $expected
83		];
84	}
85
86	/**
87	 * @dataProvider provideFetchUserIdentitiesByUserIds
88	 */
89	public function testFetchUserIdentitiesByUserIds( array $ids, array $options, array $expected ) {
90		$actors = iterator_to_array(
91			$this->getStore()
92				->newSelectQueryBuilder()
93				->whereUserIds( $ids )
94				->caller( __METHOD__ )
95				->orderByUserId( $options['sort'] ?? SelectQueryBuilder::SORT_ASC )
96				->fetchUserIdentities()
97		);
98		$this->assertCount( count( $expected ), $actors );
99		foreach ( $expected as $idx => $expectedActor ) {
100			$this->assertSameActors( $expectedActor, $actors[$idx] );
101		}
102	}
103
104	public function provideFetchUserIdentitiesByNames() {
105		yield 'default parameters' => [
106			[ 'TestUser', 'TestUser1' ], // $names
107			[], // $options
108			[
109				new UserIdentityValue( 24, 'TestUser' ),
110				new UserIdentityValue( 25, 'TestUser1' ),
111			], // $expected
112		];
113		yield 'sorted' => [
114			[ 'TestUser', 'TestUser1' ], // $names
115			[ 'sort' => UserSelectQueryBuilder::SORT_DESC ], // $options
116			[
117				new UserIdentityValue( 25, 'TestUser1' ),
118				new UserIdentityValue( 24, 'TestUser' ),
119			], // $expected
120		];
121		yield 'with IPs' => [
122			[ self::IP ], // $names
123			[], // $options
124			[
125				new UserIdentityValue( 0, self::IP ),
126			], // $expected
127		];
128		yield 'with IPs, normalization' => [
129			[ strtolower( self::IP ), self::IP ], // $names
130			[], // $options
131			[
132				new UserIdentityValue( 0, self::IP ),
133			], // $expected
134		];
135	}
136
137	/**
138	 * @dataProvider provideFetchUserIdentitiesByNames
139	 */
140	public function testFetchUserIdentitiesByNames( array $names, array $options, array $expected ) {
141		$actors = iterator_to_array(
142			$this->getStore()
143				->newSelectQueryBuilder()
144				->whereUserNames( $names )
145				->caller( __METHOD__ )
146				->orderByUserId( $options['sort'] ?? SelectQueryBuilder::SORT_ASC )
147				->fetchUserIdentities()
148		);
149		$this->assertCount( count( $expected ), $actors );
150		foreach ( $expected as $idx => $expectedActor ) {
151			$this->assertSameActors( $expectedActor, $actors[$idx] );
152		}
153	}
154
155	/**
156	 * @covers ::fetchUserIdentity
157	 */
158	public function testFetchUserIdentity() {
159		$this->assertSameActors(
160			new UserIdentityValue( 24, 'TestUser' ),
161			$this->getStore()
162				->newSelectQueryBuilder()
163				->whereUserIds( 24 )
164				->fetchUserIdentity()
165		);
166	}
167
168	/**
169	 * @covers ::fetchUserNames
170	 */
171	public function testFetchUserNames() {
172		$this->assertArrayEquals(
173			[ 'TestUser', 'TestUser1' ],
174			$this->getStore()
175				->newSelectQueryBuilder()
176				->conds( [ 'actor_id' => [ 42, 44 ] ] )
177				->fetchUserNames()
178		);
179	}
180
181	/**
182	 * @covers ::registered
183	 */
184	public function testRegistered() {
185		$actors = iterator_to_array(
186			$this->getStore()
187				->newSelectQueryBuilder()
188				->conds( [ 'actor_id' => [ 42, 43 ] ] )
189				->registered()
190				->fetchUserIdentities()
191		);
192		$this->assertCount( 1, $actors );
193		$this->assertSameActors(
194			new UserIdentityValue( 24, 'TestUser' ),
195			$actors[0]
196		);
197	}
198
199	/**
200	 * @covers ::anon
201	 */
202	public function testAnon() {
203		$actors = iterator_to_array(
204			$this->getStore()
205				->newSelectQueryBuilder()
206				->limit( 100 )
207				->whereUserNamePrefix( '' )
208				->anon()
209				->fetchUserIdentities()
210		);
211		$this->assertCount( 2, $actors );
212		$this->assertSameActors(
213			new UserIdentityValue( 0, self::IP ),
214			$actors[0]
215		);
216	}
217}
218