2019-09-04 07:27:24 +08:00
< ? php
/*
* This file is part of Flarum .
*
2019-11-28 08:16:50 +08:00
* For detailed copyright and license information , please view the
* LICENSE file that was distributed with this source code .
2019-09-04 07:27:24 +08:00
*/
namespace Flarum\Tests\integration\api\users ;
use Flarum\Settings\SettingsRepositoryInterface ;
2021-03-08 05:32:41 +08:00
use Flarum\Testing\integration\RetrievesAuthorizedUsers ;
use Flarum\Testing\integration\TestCase ;
2021-06-21 16:14:15 +08:00
use Flarum\User\RegistrationToken ;
2019-09-04 07:27:24 +08:00
use Flarum\User\User ;
2020-03-27 20:22:16 +08:00
class CreateTest extends TestCase
2019-09-04 07:27:24 +08:00
{
use RetrievesAuthorizedUsers ;
2021-01-07 11:16:26 +08:00
/**
* @ inheritDoc
*/
2020-03-28 08:26:26 +08:00
protected function setUp () : void
2019-09-04 07:27:24 +08:00
{
parent :: setUp ();
2021-05-03 13:35:46 +08:00
$this -> setting ( 'mail_driver' , 'log' );
2019-09-04 07:27:24 +08:00
}
/**
* @ test
*/
public function cannot_create_user_without_data ()
{
$response = $this -> send (
$this -> request (
2020-03-06 21:55:39 +08:00
'POST' ,
'/api/users' ,
2019-09-04 07:27:24 +08:00
[
'json' => [ 'data' => [ 'attributes' => []]],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
$this -> assertEquals ( 422 , $response -> getStatusCode ());
2019-09-04 07:44:22 +08:00
// The response body should contain details about the failed validation
$body = ( string ) $response -> getBody ();
$this -> assertJson ( $body );
$this -> assertEquals ([
'errors' => [
[
'status' => '422' ,
'code' => 'validation_error' ,
2021-02-18 05:23:13 +08:00
'detail' => 'The username field is required.' ,
2019-09-04 07:44:22 +08:00
'source' => [ 'pointer' => '/data/attributes/username' ],
],
[
'status' => '422' ,
'code' => 'validation_error' ,
2021-02-18 05:23:13 +08:00
'detail' => 'The email field is required.' ,
2019-09-04 07:44:22 +08:00
'source' => [ 'pointer' => '/data/attributes/email' ],
],
[
'status' => '422' ,
'code' => 'validation_error' ,
2021-02-18 05:23:13 +08:00
'detail' => 'The password field is required.' ,
2019-09-04 07:44:22 +08:00
'source' => [ 'pointer' => '/data/attributes/password' ],
],
],
], json_decode ( $body , true ));
2019-09-04 07:27:24 +08:00
}
/**
* @ test
*/
public function can_create_user ()
{
$response = $this -> send (
$this -> request (
2020-03-06 21:55:39 +08:00
'POST' ,
'/api/users' ,
2019-09-04 07:27:24 +08:00
[
'json' => [
'data' => [
'attributes' => [
'username' => 'test' ,
'password' => 'too-obscure' ,
'email' => 'test@machine.local' ,
],
]
],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
$this -> assertEquals ( 201 , $response -> getStatusCode ());
/** @var User $user */
$user = User :: where ( 'username' , 'test' ) -> firstOrFail ();
2020-02-14 22:34:32 +08:00
$this -> assertEquals ( 0 , $user -> is_email_confirmed );
2019-09-04 07:27:24 +08:00
$this -> assertEquals ( 'test' , $user -> username );
$this -> assertEquals ( 'test@machine.local' , $user -> email );
}
/**
* @ test
*/
public function admins_can_create_activated_users ()
{
$response = $this -> send (
$this -> request (
2020-03-06 21:55:39 +08:00
'POST' ,
'/api/users' ,
2019-09-04 07:27:24 +08:00
[
2020-03-21 01:28:28 +08:00
'authenticatedAs' => 1 ,
2019-09-04 07:27:24 +08:00
'json' => [
'data' => [
'attributes' => [
'username' => 'test' ,
'password' => 'too-obscure' ,
'email' => 'test@machine.local' ,
'isEmailConfirmed' => 1 ,
],
]
],
]
2020-03-21 01:28:28 +08:00
)
2019-09-04 07:27:24 +08:00
);
$this -> assertEquals ( 201 , $response -> getStatusCode ());
/** @var User $user */
$user = User :: where ( 'username' , 'test' ) -> firstOrFail ();
$this -> assertEquals ( 1 , $user -> is_email_confirmed );
}
/**
* @ test
*/
public function disabling_sign_up_prevents_user_creation ()
{
/** @var SettingsRepositoryInterface $settings */
2020-05-23 07:55:58 +08:00
$settings = $this -> app () -> getContainer () -> make ( SettingsRepositoryInterface :: class );
2019-09-04 07:27:24 +08:00
$settings -> set ( 'allow_sign_up' , false );
$response = $this -> send (
$this -> request (
2020-03-06 21:55:39 +08:00
'POST' ,
'/api/users' ,
2019-09-04 07:27:24 +08:00
[
'json' => [
'data' => [
'attributes' => [
'username' => 'test' ,
'password' => 'too-obscure' ,
'email' => 'test@machine.local' ,
],
]
],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
$this -> assertEquals ( 403 , $response -> getStatusCode ());
$settings -> set ( 'allow_sign_up' , true );
}
2021-06-21 16:14:15 +08:00
/**
* @ test
*/
public function cannot_create_user_with_invalid_avatar_uri_scheme ()
{
// Boot app
$this -> app ();
$regTokens = [];
// Add registration tokens that should cause a failure
$regTokens [] = [
'token' => RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'file://localhost/etc/passwd'
], []),
'scheme' => 'file'
];
$regTokens [] = [
'token' => RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'ftp://localhost/image.png'
], []),
'scheme' => 'ftp'
];
// Test each reg token
foreach ( $regTokens as $regToken ) {
$regToken [ 'token' ] -> saveOrFail ();
// Call the registration endpoint
$response = $this -> send (
$this -> request (
'POST' ,
'/api/users' ,
[
'json' => [
'data' => [
'attributes' => [
'token' => $regToken [ 'token' ] -> token ,
],
]
],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
// The response body should contain details about the invalid URI
$body = ( string ) $response -> getBody ();
$this -> assertJson ( $body );
$decodedBody = json_decode ( $body , true );
$this -> assertEquals ( 500 , $response -> getStatusCode ());
$firstError = $decodedBody [ 'errors' ][ 0 ];
// Check that the error is an invalid URI
$this -> assertStringStartsWith ( 'InvalidArgumentException: Provided avatar URL must have scheme http or https. Scheme provided was ' . $regToken [ 'scheme' ] . '.' , $firstError [ 'detail' ]);
}
}
/**
* @ test
*/
public function cannot_create_user_with_invalid_avatar_uri ()
{
// Boot app
$this -> app ();
$regTokens = [];
// Add registration tokens that should cause a failure
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'https://127.0.0.1/image.png'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'https://192.168.0.1/image.png'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => '../image.png'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test' ,
'email' => 'test@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'image.png'
], []);
// Test each reg token
foreach ( $regTokens as $regToken ) {
$regToken -> saveOrFail ();
// Call the registration endpoint
$response = $this -> send (
$this -> request (
'POST' ,
'/api/users' ,
[
'json' => [
'data' => [
'attributes' => [
'token' => $regToken -> token ,
],
]
],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
// The response body should contain details about the invalid URI
$body = ( string ) $response -> getBody ();
$this -> assertJson ( $body );
$decodedBody = json_decode ( $body , true );
$this -> assertEquals ( 500 , $response -> getStatusCode ());
$firstError = $decodedBody [ 'errors' ][ 0 ];
// Check that the error is an invalid URI
$this -> assertStringStartsWith ( 'InvalidArgumentException: Provided avatar URL must be a valid URI.' , $firstError [ 'detail' ]);
}
}
/**
* @ test
*/
public function can_create_user_with_valid_avatar_uri ()
{
// Boot app
$this -> app ();
$regTokens = [];
// Add registration tokens that should work fine
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '1' , [
'username' => 'test1' ,
'email' => 'test1@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'https://via.placeholder.com/150.png'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '2' , [
'username' => 'test2' ,
'email' => 'test2@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'https://via.placeholder.com/150.jpg'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '3' , [
'username' => 'test3' ,
'email' => 'test3@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'https://via.placeholder.com/150.gif'
], []);
$regTokens [] = RegistrationToken :: generate ( 'flarum' , '4' , [
'username' => 'test4' ,
'email' => 'test4@machine.local' ,
'is_email_confirmed' => 1 ,
'avatar_url' => 'http://via.placeholder.com/150.png'
], []);
/**
* Test each reg token .
*
* @ var RegistrationToken $regToken
*/
foreach ( $regTokens as $regToken ) {
$regToken -> saveOrFail ();
// Call the registration endpoint
$response = $this -> send (
$this -> request (
'POST' ,
'/api/users' ,
[
'json' => [
'data' => [
'attributes' => [
'token' => $regToken -> token ,
],
]
],
]
) -> withAttribute ( 'bypassCsrfToken' , true )
);
$this -> assertEquals ( 201 , $response -> getStatusCode ());
$user = User :: where ( 'username' , $regToken -> user_attributes [ 'username' ]) -> firstOrFail ();
$this -> assertEquals ( $regToken -> user_attributes [ 'is_email_confirmed' ], $user -> is_email_confirmed );
$this -> assertEquals ( $regToken -> user_attributes [ 'username' ], $user -> username );
$this -> assertEquals ( $regToken -> user_attributes [ 'email' ], $user -> email );
}
}
2019-09-04 07:27:24 +08:00
}