mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-14 09:34:10 -08:00
341 lines
14 KiB
PHP
341 lines
14 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Importing\Api;
|
|
|
|
use App\Models\Location;
|
|
use App\Models\User;
|
|
use Database\Factories\AssetFactory;
|
|
use Illuminate\Support\Str;
|
|
use Database\Factories\UserFactory;
|
|
use Database\Factories\ImportFactory;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Illuminate\Foundation\Testing\WithFaker;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Testing\TestResponse;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use Tests\Support\Importing\UsersImportFileBuilder as ImportFileBuilder;
|
|
|
|
class ImportUsersTest extends ImportDataTestCase
|
|
{
|
|
use WithFaker;
|
|
|
|
protected function importFileResponse(array $parameters = []): TestResponse
|
|
{
|
|
if (!array_key_exists('import-type', $parameters)) {
|
|
$parameters['import-type'] = 'user';
|
|
}
|
|
|
|
return parent::importFileResponse($parameters);
|
|
}
|
|
|
|
#[Test]
|
|
#[DataProvider('permissionsTestData')]
|
|
public function onlyUserWithPermissionCanImportUsers(array|string $permissions): void
|
|
{
|
|
$permissions = collect((array) $permissions)
|
|
->map(fn (string $permission) => [$permission => '1'])
|
|
->toJson();
|
|
|
|
$this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions]));
|
|
|
|
$this->importFileResponse(['import' => 44])->assertForbidden();
|
|
}
|
|
|
|
#[Test]
|
|
public function userWithImportAssetsPermissionCanImportUsers(): void
|
|
{
|
|
$this->actingAsForApi(UserFactory::new()->canImport()->create());
|
|
|
|
$import = ImportFactory::new()->users()->create();
|
|
|
|
$this->importFileResponse(['import' => $import->id])->assertOk();
|
|
}
|
|
|
|
#[Test]
|
|
public function importUsers(): void
|
|
{
|
|
Notification::fake();
|
|
|
|
$importFileBuilder = ImportFileBuilder::new();
|
|
$row = $importFileBuilder->firstRow();
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
$this->importFileResponse(['import' => $import->id, 'send-welcome' => 1])
|
|
->assertOk()
|
|
->assertExactJson([
|
|
'payload' => null,
|
|
'status' => 'success',
|
|
'messages' => ['redirect_url' => route('users.index')]
|
|
]);
|
|
|
|
$newUser = User::query()
|
|
->with(['company', 'location'])
|
|
->where('username', $row['username'])
|
|
->sole();
|
|
|
|
Notification::assertNothingSent();
|
|
|
|
$this->assertEquals($newUser->email, $row['email']);
|
|
$this->assertEquals($newUser->first_name, $row['firstName']);
|
|
$this->assertEquals($newUser->last_name, $row['lastName']);
|
|
$this->assertEquals($newUser->employee_num, $row['employeeNumber']);
|
|
$this->assertEquals($newUser->company->name, $row['companyName']);
|
|
$this->assertEquals($newUser->location->name, $row['location']);
|
|
$this->assertEquals($newUser->phone, $row['phoneNumber']);
|
|
$this->assertEquals($newUser->jobtitle, $row['position']);
|
|
$this->assertTrue(Hash::isHashed($newUser->password));
|
|
$this->assertEquals($newUser->website, '');
|
|
$this->assertEquals($newUser->country, '');
|
|
$this->assertEquals($newUser->address, '');
|
|
$this->assertEquals($newUser->city, '');
|
|
$this->assertEquals($newUser->state, '');
|
|
$this->assertEquals($newUser->zip, '');
|
|
$this->assertNull($newUser->permissions);
|
|
$this->assertNull($newUser->avatar);
|
|
$this->assertNull($newUser->notes);
|
|
$this->assertNull($newUser->skin);
|
|
$this->assertNull($newUser->department_id);
|
|
$this->assertNull($newUser->two_factor_secret);
|
|
$this->assertNull($newUser->idap_import);
|
|
$this->assertEquals($newUser->locale, 'en-US');
|
|
$this->assertEquals($newUser->show_in_list, 1);
|
|
$this->assertEquals($newUser->two_factor_enrolled, 0);
|
|
$this->assertEquals($newUser->two_factor_optin, 0);
|
|
$this->assertEquals($newUser->remote, 0);
|
|
$this->assertEquals($newUser->autoassign_licenses, 0);
|
|
$this->assertEquals($newUser->vip, 0);
|
|
$this->assertEquals($newUser->enable_sounds, 0);
|
|
$this->assertEquals($newUser->enable_confetti, 0);
|
|
$this->assertNull($newUser->created_by);
|
|
$this->assertNull($newUser->start_date);
|
|
$this->assertNull($newUser->end_date);
|
|
$this->assertNull($newUser->scim_externalid);
|
|
$this->assertNull($newUser->manager_id);
|
|
$this->assertNull($newUser->activation_code);
|
|
$this->assertNull($newUser->last_login);
|
|
$this->assertNull($newUser->persist_code);
|
|
$this->assertNull($newUser->reset_password_code);
|
|
$this->assertEquals($newUser->activated, 0);
|
|
}
|
|
|
|
#[Test]
|
|
public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void
|
|
{
|
|
$row = ImportFileBuilder::new()->definition();
|
|
$row['unknownColumnInCsvFile'] = 'foo';
|
|
|
|
$importFileBuilder = new ImportFileBuilder([$row]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->importFileResponse(['import' => $import->id])->assertOk();
|
|
}
|
|
|
|
#[Test]
|
|
public function willNotCreateNewUserWhenUserWithUserNameAlreadyExist(): void
|
|
{
|
|
$user = UserFactory::new()->create(['username' => Str::random()]);
|
|
$importFileBuilder = ImportFileBuilder::times(4)->replace(['username' => $user->username]);
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
$this->importFileResponse(['import' => $import->id])->assertOk();
|
|
|
|
$probablyNewUsers = User::query()
|
|
->where('username', $user->username)
|
|
->get();
|
|
|
|
$this->assertCount(1, $probablyNewUsers);
|
|
}
|
|
|
|
#[Test]
|
|
public function willGenerateUsernameWhenUsernameFieldIsMissing(): void
|
|
{
|
|
$importFileBuilder = ImportFileBuilder::new()->forget('username');
|
|
$row = $importFileBuilder->firstRow();
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
$this->importFileResponse(['import' => $import->id])->assertOk();
|
|
|
|
$newUser = User::query()
|
|
->where('email', $row['email'])
|
|
->sole();
|
|
|
|
$generatedUsername = User::generateFormattedNameFromFullName("{$row['firstName']} {$row['lastName']}")['username'];
|
|
|
|
$this->assertEquals($newUser->username, $generatedUsername);
|
|
}
|
|
|
|
#[Test]
|
|
public function willUpdateLocationOfAllAssetsAssignedToUser(): void
|
|
{
|
|
$user = UserFactory::new()->create(['username' => Str::random()]);
|
|
$assetsAssignedToUser = AssetFactory::new()->create(['assigned_to' => $user->id, 'assigned_type' => User::class]);
|
|
$importFileBuilder = ImportFileBuilder::new(['username' => $user->username]);
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
$this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk();
|
|
|
|
$userLocation = Location::query()->where('name', $importFileBuilder->firstRow()['location'])->sole(['id']);
|
|
|
|
$this->assertEquals(
|
|
$assetsAssignedToUser->refresh()->location_id,
|
|
$userLocation->id
|
|
);
|
|
}
|
|
|
|
#[Test]
|
|
public function whenRequiredColumnsAreMissingInImportFile(): void
|
|
{
|
|
$importFileBuilder = ImportFileBuilder::new(['firstName' => ''])->forget(['username']);
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
|
|
$this->importFileResponse(['import' => $import->id])
|
|
->assertInternalServerError()
|
|
->assertExactJson([
|
|
'status' => 'import-errors',
|
|
'payload' => null,
|
|
'messages' => [
|
|
'' => [
|
|
'User' => [
|
|
'first_name' => ['The first name field is required.'],
|
|
]
|
|
]
|
|
]
|
|
]);
|
|
|
|
$newUsers = User::query()
|
|
->where('email', $importFileBuilder->firstRow()['email'])
|
|
->get();
|
|
|
|
$this->assertCount(0, $newUsers);
|
|
}
|
|
|
|
#[Test]
|
|
public function updateUserFromImport(): void
|
|
{
|
|
$user = UserFactory::new()->create(['username' => Str::random()])->refresh();
|
|
$importFileBuilder = ImportFileBuilder::new(['username' => $user->username]);
|
|
|
|
$row = $importFileBuilder->firstRow();
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
$this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk();
|
|
|
|
$updatedUser = User::query()->with(['company', 'location'])->find($user->id);
|
|
$updatedAttributes = [
|
|
'first_name', 'email', 'last_name', 'employee_num', 'company',
|
|
'location_id', 'company_id', 'updated_at', 'phone', 'jobtitle'
|
|
];
|
|
|
|
$this->assertEquals($updatedUser->email, $row['email']);
|
|
$this->assertEquals($updatedUser->first_name, $row['firstName']);
|
|
$this->assertEquals($updatedUser->last_name, $row['lastName']);
|
|
$this->assertEquals($updatedUser->employee_num, $row['employeeNumber']);
|
|
$this->assertEquals($updatedUser->company->name, $row['companyName']);
|
|
$this->assertEquals($updatedUser->location->name, $row['location']);
|
|
$this->assertEquals($updatedUser->phone, $row['phoneNumber']);
|
|
$this->assertEquals($updatedUser->jobtitle, $row['position']);
|
|
$this->assertTrue(Hash::isHashed($updatedUser->password));
|
|
|
|
$this->assertEquals(
|
|
Arr::except($updatedUser->attributesToArray(), $updatedAttributes),
|
|
Arr::except($user->attributesToArray(), $updatedAttributes),
|
|
);
|
|
}
|
|
|
|
#[Test]
|
|
public function customColumnMapping(): void
|
|
{
|
|
$faker = ImportFileBuilder::new()->definition();
|
|
$row = [
|
|
'companyName' => $faker['username'],
|
|
'email' => $faker['position'],
|
|
'employeeNumber' => $faker['phoneNumber'],
|
|
'firstName' => $faker['location'],
|
|
'lastName' => $faker['lastName'],
|
|
'location' => $faker['firstName'],
|
|
'phoneNumber' => $faker['employeeNumber'],
|
|
'position' => $faker['email'],
|
|
'username' => $faker['companyName'],
|
|
];
|
|
|
|
$importFileBuilder = new ImportFileBuilder([$row]);
|
|
$import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]);
|
|
|
|
$this->actingAsForApi(UserFactory::new()->superuser()->create());
|
|
|
|
$this->importFileResponse([
|
|
'import' => $import->id,
|
|
'column-mappings' => [
|
|
'Company' => 'username',
|
|
'email' => 'jobtitle',
|
|
'Employee Number' => 'phone_number',
|
|
'First Name' => 'location',
|
|
'Last Name' => 'last_name',
|
|
'Location' => 'first_name',
|
|
'Phone Number' => 'employee_num',
|
|
'Job Title' => 'email',
|
|
'Username' => 'company',
|
|
]
|
|
])->assertOk();
|
|
|
|
$newUser = User::query()
|
|
->with(['company', 'location'])
|
|
->where('username', $row['companyName'])
|
|
->sole();
|
|
|
|
$this->assertEquals($newUser->email, $row['position']);
|
|
$this->assertEquals($newUser->first_name, $row['location']);
|
|
$this->assertEquals($newUser->last_name, $row['lastName']);
|
|
$this->assertEquals($newUser->jobtitle, $row['email']);
|
|
$this->assertEquals($newUser->employee_num, $row['phoneNumber']);
|
|
$this->assertEquals($newUser->company->name, $row['username']);
|
|
$this->assertEquals($newUser->location->name, $row['firstName']);
|
|
$this->assertEquals($newUser->phone, $row['employeeNumber']);
|
|
$this->assertTrue(Hash::isHashed($newUser->password));
|
|
$this->assertEquals($newUser->website, '');
|
|
$this->assertEquals($newUser->country, '');
|
|
$this->assertEquals($newUser->address, '');
|
|
$this->assertEquals($newUser->city, '');
|
|
$this->assertEquals($newUser->state, '');
|
|
$this->assertEquals($newUser->zip, '');
|
|
$this->assertNull($newUser->permissions);
|
|
$this->assertNull($newUser->avatar);
|
|
$this->assertNull($newUser->notes);
|
|
$this->assertNull($newUser->skin);
|
|
$this->assertNull($newUser->department_id);
|
|
$this->assertNull($newUser->two_factor_secret);
|
|
$this->assertNull($newUser->idap_import);
|
|
$this->assertEquals($newUser->locale, 'en-US');
|
|
$this->assertEquals($newUser->show_in_list, 1);
|
|
$this->assertEquals($newUser->two_factor_enrolled, 0);
|
|
$this->assertEquals($newUser->two_factor_optin, 0);
|
|
$this->assertEquals($newUser->remote, 0);
|
|
$this->assertEquals($newUser->autoassign_licenses, 0);
|
|
$this->assertEquals($newUser->vip, 0);
|
|
$this->assertEquals($newUser->enable_sounds, 0);
|
|
$this->assertEquals($newUser->enable_confetti, 0);
|
|
$this->assertNull($newUser->created_by);
|
|
$this->assertNull($newUser->start_date);
|
|
$this->assertNull($newUser->end_date);
|
|
$this->assertNull($newUser->scim_externalid);
|
|
$this->assertNull($newUser->manager_id);
|
|
$this->assertNull($newUser->activation_code);
|
|
$this->assertNull($newUser->last_login);
|
|
$this->assertNull($newUser->persist_code);
|
|
$this->assertNull($newUser->reset_password_code);
|
|
$this->assertEquals($newUser->activated, 0);
|
|
}
|
|
}
|