Page MenuHomePhorge

D1213.1774873000.diff
No OneTemporary

Authored By
Unknown
Size
65 KB
Referenced Files
None
Subscribers
None

D1213.1774873000.diff

diff --git a/src/app/Backends/LDAP.php b/src/app/Backends/LDAP.php
--- a/src/app/Backends/LDAP.php
+++ b/src/app/Backends/LDAP.php
@@ -7,6 +7,13 @@
class LDAP
{
+ /** @const array UserSettings used by th backend */
+ public const USER_SETTINGS = [
+ 'first_name',
+ 'last_name',
+ 'organization',
+ ];
+
/**
* Create a domain in LDAP.
*
@@ -368,11 +375,9 @@
$entry['givenname'] = $firstName;
$entry['sn'] = $lastName;
$entry['userpassword'] = $user->password_ldap;
-
$entry['inetuserstatus'] = $user->status;
-
+ $entry['o'] = $user->getSetting('organization');
$entry['mailquota'] = 0;
-
$entry['alias'] = $user->aliases->pluck('alias')->toArray();
$roles = [];
diff --git a/src/app/Http/Controllers/API/SignupController.php b/src/app/Http/Controllers/API/SignupController.php
--- a/src/app/Http/Controllers/API/SignupController.php
+++ b/src/app/Http/Controllers/API/SignupController.php
@@ -71,26 +71,33 @@
$request->all(),
[
'email' => 'required',
- 'name' => 'required|max:512',
+ 'first_name' => 'max:128',
+ 'last_name' => 'max:128',
'plan' => 'nullable|alpha_num|max:128',
'voucher' => 'max:32',
]
);
- if ($v->fails()) {
- return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
- }
+ $is_phone = false;
+ $errors = $v->fails() ? $v->errors()->toArray() : [];
// Validate user email (or phone)
- if ($error = $this->validatePhoneOrEmail($request->email, $is_phone)) {
- return response()->json(['status' => 'error', 'errors' => ['email' => $error]], 422);
+ if (empty($errors['email'])) {
+ if ($error = $this->validatePhoneOrEmail($request->email, $is_phone)) {
+ $errors['email'] = $error;
+ }
+ }
+
+ if (!empty($errors)) {
+ return response()->json(['status' => 'error', 'errors' => $errors], 422);
}
// Generate the verification code
$code = SignupCode::create([
'data' => [
'email' => $request->email,
- 'name' => $request->name,
+ 'first_name' => $request->first_name,
+ 'last_name' => $request->last_name,
'plan' => $request->plan,
'voucher' => $request->voucher,
]
@@ -151,7 +158,8 @@
return response()->json([
'status' => 'success',
'email' => $code->data['email'],
- 'name' => $code->data['name'],
+ 'first_name' => $code->data['first_name'],
+ 'last_name' => $code->data['last_name'],
'voucher' => $code->data['voucher'],
'is_domain' => $has_domain,
'domains' => $has_domain ? [] : Domain::getPublicDomains(),
@@ -213,7 +221,6 @@
// Get user name/email from the verification code database
$code_data = $v->getData();
- $user_name = $code_data->name;
$user_email = $code_data->email;
// We allow only ASCII, so we can safely lower-case the email address
@@ -224,7 +231,6 @@
// Create user record
$user = User::create([
- 'name' => $user_name,
'email' => $login . '@' . $domain,
'password' => $request->password,
]);
@@ -248,7 +254,11 @@
$user->assignPlan($plan, $domain);
// Save the external email and plan in user settings
- $user->setSetting('external_email', $user_email);
+ $user->setSettings([
+ 'external_email' => $user_email,
+ 'first_name' => $code_data->first_name,
+ 'last_name' => $code_data->last_name,
+ ]);
// Remove the verification code
$this->code->delete();
diff --git a/src/app/Http/Controllers/API/V4/PaymentsController.php b/src/app/Http/Controllers/API/V4/PaymentsController.php
--- a/src/app/Http/Controllers/API/V4/PaymentsController.php
+++ b/src/app/Http/Controllers/API/V4/PaymentsController.php
@@ -47,7 +47,7 @@
if (empty($customer_id)) {
$customer = mollie()->customers()->create([
- 'name' => $current_user->name,
+ 'name' => $current_user->name(),
'email' => $current_user->email,
]);
diff --git a/src/app/Http/Controllers/API/V4/UsersController.php b/src/app/Http/Controllers/API/V4/UsersController.php
--- a/src/app/Http/Controllers/API/V4/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/UsersController.php
@@ -16,6 +16,18 @@
class UsersController extends Controller
{
+ // List of user settings keys available for modification in UI
+ public const USER_SETTINGS = [
+ 'billing_address',
+ 'country',
+ 'currency',
+ 'external_email',
+ 'first_name',
+ 'last_name',
+ 'organization',
+ 'phone',
+ ];
+
/**
* Delete a user.
*
@@ -178,16 +190,10 @@
return response()->json(['status' => 'error', 'errors' => $errors], 422);
}
- $user_name = !empty($settings['first_name']) ? $settings['first_name'] : '';
- if (!empty($settings['last_name'])) {
- $user_name .= ' ' . $settings['last_name'];
- }
-
DB::beginTransaction();
// Create user record
$user = User::create([
- 'name' => $user_name,
'email' => $request->email,
'password' => $request->password,
]);
@@ -342,10 +348,8 @@
$response = $user->toArray();
// Settings
- // TODO: It might be reasonable to limit the list of settings here to these
- // that are safe and are used in the UI
$response['settings'] = [];
- foreach ($user->settings as $item) {
+ foreach ($user->settings()->whereIn('key', self::USER_SETTINGS)->get() as $item) {
$response['settings'][$item->key] = $item->value;
}
@@ -416,8 +420,9 @@
$rules = [
'external_email' => 'nullable|email',
'phone' => 'string|nullable|max:64|regex:/^[0-9+() -]+$/',
- 'first_name' => 'string|nullable|max:512',
- 'last_name' => 'string|nullable|max:512',
+ 'first_name' => 'string|nullable|max:128',
+ 'last_name' => 'string|nullable|max:128',
+ 'organization' => 'string|nullable|max:512',
'billing_address' => 'string|nullable|max:1024',
'country' => 'string|nullable|alpha|size:2',
'currency' => 'string|nullable|alpha|size:3',
diff --git a/src/app/Mail/PasswordReset.php b/src/app/Mail/PasswordReset.php
--- a/src/app/Mail/PasswordReset.php
+++ b/src/app/Mail/PasswordReset.php
@@ -49,7 +49,7 @@
'code' => $this->code->code,
'short_code' => $this->code->short_code,
'link' => sprintf('<a href="%s">%s</a>', $href, $href),
- 'username' => $this->code->user->name
+ 'username' => $this->code->user->name(true)
]);
return $this;
diff --git a/src/app/Observers/UserObserver.php b/src/app/Observers/UserObserver.php
--- a/src/app/Observers/UserObserver.php
+++ b/src/app/Observers/UserObserver.php
@@ -46,17 +46,30 @@
*/
public function created(User $user)
{
- // FIXME: Actual proper settings
- $user->setSettings(
- [
- 'country' => 'CH',
- 'currency' => 'CHF',
- 'first_name' => '',
- 'last_name' => '',
- 'billing_address' => '',
- 'organization' => ''
- ]
- );
+ $settings = [
+ 'country' => 'CH',
+ 'currency' => 'CHF',
+ /*
+ 'first_name' => '',
+ 'last_name' => '',
+ 'billing_address' => '',
+ 'organization' => '',
+ 'phone' => '',
+ 'external_email' => '',
+ */
+ ];
+
+ foreach ($settings as $key => $value) {
+ $settings[$key] = [
+ 'key' => $key,
+ 'value' => $value,
+ 'user_id' => $user->id,
+ ];
+ }
+
+ // Note: Don't use setSettings() here to bypass UserSetting observers
+ // Note: This is a single multi-insert query
+ $user->settings()->insert(array_values($settings));
$user->wallets()->create();
diff --git a/src/app/Observers/UserSettingObserver.php b/src/app/Observers/UserSettingObserver.php
--- a/src/app/Observers/UserSettingObserver.php
+++ b/src/app/Observers/UserSettingObserver.php
@@ -2,6 +2,7 @@
namespace App\Observers;
+use App\Backends\LDAP;
use App\UserSetting;
class UserSettingObserver
@@ -9,55 +10,42 @@
/**
* Handle the user setting "created" event.
*
- * @param \App\UserSetting $userSetting
+ * @param \App\UserSetting $userSetting Settings object
+ *
* @return void
*/
public function created(UserSetting $userSetting)
{
- //
+ if (in_array($userSetting->key, LDAP::USER_SETTINGS)) {
+ \App\Jobs\UserUpdate::dispatch($userSetting->user);
+ }
}
/**
* Handle the user setting "updated" event.
*
- * @param \App\UserSetting $userSetting
+ * @param \App\UserSetting $userSetting Settings object
+ *
* @return void
*/
public function updated(UserSetting $userSetting)
{
- \App\Jobs\UserUpdate::dispatch($userSetting->user);
+ if (in_array($userSetting->key, LDAP::USER_SETTINGS)) {
+ \App\Jobs\UserUpdate::dispatch($userSetting->user);
+ }
}
/**
* Handle the user setting "deleted" event.
*
- * @param \App\UserSetting $userSetting
- * @return void
- */
- public function deleted(UserSetting $userSetting)
- {
- //
- }
-
- /**
- * Handle the user setting "restored" event.
+ * @param \App\UserSetting $userSetting Settings object
*
- * @param \App\UserSetting $userSetting
* @return void
*/
- public function restored(UserSetting $userSetting)
- {
- //
- }
-
- /**
- * Handle the user setting "force deleted" event.
- *
- * @param \App\UserSetting $userSetting
- * @return void
- */
- public function forceDeleted(UserSetting $userSetting)
+ public function deleted(UserSetting $userSetting)
{
- //
+ if (in_array($userSetting->key, LDAP::USER_SETTINGS)) {
+ \App\Jobs\UserUpdate::dispatch($userSetting->user);
+ }
}
}
diff --git a/src/app/Traits/UserSettingsTrait.php b/src/app/Traits/UserSettingsTrait.php
--- a/src/app/Traits/UserSettingsTrait.php
+++ b/src/app/Traits/UserSettingsTrait.php
@@ -81,7 +81,9 @@
private function storeSetting(string $key, $value): void
{
if ($value === null || $value === '') {
- UserSetting::where(['user_id' => $this->id, 'key' => $key])->delete();
+ if ($setting = UserSetting::where(['user_id' => $this->id, 'key' => $key])->first()) {
+ $setting->delete();
+ }
} else {
UserSetting::updateOrCreate(
['user_id' => $this->id, 'key' => $key],
diff --git a/src/app/User.php b/src/app/User.php
--- a/src/app/User.php
+++ b/src/app/User.php
@@ -8,7 +8,6 @@
use App\Traits\UserSettingsTrait;
use App\Wallet;
use Illuminate\Notifications\Notifiable;
-use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Iatstuti\Database\Support\NullableFields;
@@ -19,7 +18,6 @@
*
* @property string $email
* @property int $id
- * @property string $name
* @property string $password
* @property int $status
*/
@@ -55,7 +53,6 @@
* @var array
*/
protected $fillable = [
- 'name',
'email',
'password',
'password_ldap',
@@ -70,26 +67,15 @@
protected $hidden = [
'password',
'password_ldap',
- 'remember_token',
'role'
];
protected $nullable = [
- 'name',
'password',
'password_ldap'
];
/**
- * The attributes that should be cast to native types.
- *
- * @var array
- */
- protected $casts = [
- 'email_verified_at' => 'datetime',
- ];
-
- /**
* Any wallets on which this user is a controller.
*
* This does not include wallets owned by the user.
@@ -457,6 +443,27 @@
}
/**
+ * A shortcut to get the user name.
+ *
+ * @param bool $fallback Return "<aa.name> User" if there's no name
+ *
+ * @return string Full user name
+ */
+ public function name(bool $fallback = false): string
+ {
+ $firstname = $this->getSetting('first_name');
+ $lastname = $this->getSetting('last_name');
+
+ $name = trim($firstname . ' ' . $lastname);
+
+ if (empty($name) && $fallback) {
+ return \config('app.name') . ' User';
+ }
+
+ return $name;
+ }
+
+ /**
* Any (additional) properties of this user.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
diff --git a/src/composer.json b/src/composer.json
--- a/src/composer.json
+++ b/src/composer.json
@@ -42,7 +42,7 @@
"nunomaduro/collision": "^3.0",
"nunomaduro/larastan": "^0.4",
"phpstan/phpstan": "0.11.19",
- "phpunit/phpunit": "^7.5"
+ "phpunit/phpunit": "^8"
},
"config": {
"optimize-autoloader": true,
diff --git a/src/database/factories/UserFactory.php b/src/database/factories/UserFactory.php
--- a/src/database/factories/UserFactory.php
+++ b/src/database/factories/UserFactory.php
@@ -20,9 +20,7 @@
User::class,
function (Faker $faker) {
return [
- 'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
- 'email_verified_at' => now(),
'password' => Str::random(64)
];
}
diff --git a/src/database/migrations/2014_10_12_000000_create_users_table.php b/src/database/migrations/2014_10_12_000000_create_users_table.php
--- a/src/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/src/database/migrations/2014_10_12_000000_create_users_table.php
@@ -17,13 +17,11 @@
'users',
function (Blueprint $table) {
$table->bigInteger('id');
- $table->string('name')->nullable();
$table->string('email')->unique();
- $table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->string('password_ldap')->nullable();
$table->smallinteger('status');
- $table->rememberToken();
+// $table->rememberToken();
$table->timestamps();
$table->primary('id');
diff --git a/src/database/seeds/UserSeeder.php b/src/database/seeds/UserSeeder.php
--- a/src/database/seeds/UserSeeder.php
+++ b/src/database/seeds/UserSeeder.php
@@ -32,10 +32,8 @@
$john = User::create(
[
- 'name' => 'John Doe',
'email' => 'john@kolab.org',
'password' => 'simple123',
- 'email_verified_at' => now()
]
);
@@ -47,6 +45,7 @@
'country' => 'US',
'billing_address' => "601 13th Street NW\nSuite 900 South\nWashington, DC 20005",
'external_email' => 'john.doe.external@gmail.com',
+ 'organization' => 'Kolab Developers',
'phone' => '+1 509-248-1111',
]
);
@@ -64,10 +63,8 @@
$jack = User::create(
[
- 'name' => 'Jack Daniels',
'email' => 'jack@kolab.org',
'password' => 'simple123',
- 'email_verified_at' => now()
]
);
@@ -92,10 +89,8 @@
$ned = User::create(
[
- 'name' => 'Edward Flanders',
'email' => 'ned@kolab.org',
'password' => 'simple123',
- 'email_verified_at' => now()
]
);
@@ -122,10 +117,8 @@
$joe = User::create(
[
- 'name' => 'Joe Sixpack',
'email' => 'joe@kolab.org',
'password' => 'simple123',
- 'email_verified_at' => now()
]
);
@@ -135,10 +128,8 @@
$jeroen = User::create(
[
- 'name' => 'Jeroen van Meeuwen',
'email' => 'jeroen@jeroen.jeroen',
'password' => 'jeroen',
- 'email_verified_at' => now()
]
);
diff --git a/src/resources/vue/Admin/User.vue b/src/resources/vue/Admin/User.vue
--- a/src/resources/vue/Admin/User.vue
+++ b/src/resources/vue/Admin/User.vue
@@ -41,6 +41,12 @@
<span class="form-control-plaintext" id="last_name">{{ user.last_name }}</span>
</div>
</div>
+ <div class="form-group row mb-0" v-if="user.organization">
+ <label for="organization" class="col-sm-4 col-form-label">Organization</label>
+ <div class="col-sm-8">
+ <span class="form-control-plaintext" id="organization">{{ user.organization }}</span>
+ </div>
+ </div>
<div class="form-group row mb-0" v-if="user.phone">
<label for="phone" class="col-sm-4 col-form-label">Phone</label>
<div class="col-sm-8">
@@ -106,7 +112,7 @@
<div class="card-text">
<form>
<div class="form-group row mb-0">
- <label for="first_name" class="col-sm-2 col-form-label">Discount:</label>
+ <label class="col-sm-2 col-form-label">Discount:</label>
<div class="col-sm-10">
<span class="form-control-plaintext" id="discount">
<span>{{ wallet_discount ? (wallet_discount + '% - ' + wallet_discount_description) : 'none' }}</span>
@@ -292,7 +298,7 @@
this.user = response.data
- let keys = ['first_name', 'last_name', 'external_email', 'billing_address', 'phone']
+ let keys = ['first_name', 'last_name', 'external_email', 'billing_address', 'phone', 'organization']
let country = this.user.settings.country
if (country) {
diff --git a/src/resources/vue/Signup.vue b/src/resources/vue/Signup.vue
--- a/src/resources/vue/Signup.vue
+++ b/src/resources/vue/Signup.vue
@@ -26,8 +26,10 @@
</p>
<form @submit.prevent="submitStep1" data-validation-prefix="signup_">
<div class="form-group">
- <label for="signup_name" class="sr-only">Your Name</label>
- <input type="text" class="form-control" id="signup_name" placeholder="Your Name" required autofocus v-model="name">
+ <div class="input-group">
+ <input type="text" class="form-control" id="signup_first_name" placeholder="First Name" autofocus v-model="first_name">
+ <input type="text" class="form-control rounded-right" id="signup_last_name" placeholder="Surname" v-model="last_name">
+ </div>
</div>
<div class="form-group">
<label for="signup_email" class="sr-only">Existing Email Address</label>
@@ -101,7 +103,8 @@
data() {
return {
email: '',
- name: '',
+ first_name: '',
+ last_name: '',
code: '',
short_code: '',
login: '',
@@ -162,7 +165,8 @@
axios.post('/api/auth/signup/init', {
email: this.email,
- name: this.name,
+ last_name: this.last_name,
+ first_name: this.first_name,
plan: this.plan,
voucher: this.voucher
}).then(response => {
@@ -184,7 +188,8 @@
}).then(response => {
this.displayForm(3, true)
// Reset user name/email/plan, we don't have them if user used a verification link
- this.name = response.data.name
+ this.first_name = response.data.first_name
+ this.last_name = response.data.last_name
this.email = response.data.email
this.is_domain = response.data.is_domain
this.voucher = response.data.voucher
diff --git a/src/resources/vue/User/Info.vue b/src/resources/vue/User/Info.vue
--- a/src/resources/vue/User/Info.vue
+++ b/src/resources/vue/User/Info.vue
@@ -25,6 +25,12 @@
</div>
</div>
<div class="form-group row">
+ <label for="organization" class="col-sm-4 col-form-label">Organization</label>
+ <div class="col-sm-8">
+ <input type="text" class="form-control" id="organization" v-model="user.organization">
+ </div>
+ </div>
+ <div class="form-group row">
<label for="email" class="col-sm-4 col-form-label">Email</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="email" :disabled="user_id !== 'new'" required v-model="user.email">
@@ -193,6 +199,7 @@
this.user = response.data
this.user.first_name = response.data.settings.first_name
this.user.last_name = response.data.settings.last_name
+ this.user.organization = response.data.settings.organization
this.discount = this.user.wallet.discount
this.discount_description = this.user.wallet.discount_description
diff --git a/src/resources/vue/User/Profile.vue b/src/resources/vue/User/Profile.vue
--- a/src/resources/vue/User/Profile.vue
+++ b/src/resources/vue/User/Profile.vue
@@ -18,6 +18,12 @@
</div>
</div>
<div class="form-group row">
+ <label for="organization" class="col-sm-4 col-form-label">Organization</label>
+ <div class="col-sm-8">
+ <input type="text" class="form-control" id="organization" v-model="profile.organization">
+ </div>
+ </div>
+ <div class="form-group row">
<label for="phone" class="col-sm-4 col-form-label">Phone</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="phone" v-model="profile.phone">
diff --git a/src/tests/Browser/Admin/UserTest.php b/src/tests/Browser/Admin/UserTest.php
--- a/src/tests/Browser/Admin/UserTest.php
+++ b/src/tests/Browser/Admin/UserTest.php
@@ -180,7 +180,7 @@
->with('@user-info form', function (Browser $browser) use ($john) {
$ext_email = $john->getSetting('external_email');
- $browser->assertElementsCount('.row', 8)
+ $browser->assertElementsCount('.row', 9)
->assertSeeIn('.row:nth-child(1) label', 'ID (Created at)')
->assertSeeIn('.row:nth-child(1) #userid', "{$john->id} ({$john->created_at})")
->assertSeeIn('.row:nth-child(2) label', 'Status')
@@ -189,15 +189,17 @@
->assertSeeIn('.row:nth-child(3) #first_name', 'John')
->assertSeeIn('.row:nth-child(4) label', 'Last name')
->assertSeeIn('.row:nth-child(4) #last_name', 'Doe')
- ->assertSeeIn('.row:nth-child(5) label', 'Phone')
- ->assertSeeIn('.row:nth-child(5) #phone', $john->getSetting('phone'))
- ->assertSeeIn('.row:nth-child(6) label', 'External email')
- ->assertSeeIn('.row:nth-child(6) #external_email a', $ext_email)
- ->assertAttribute('.row:nth-child(6) #external_email a', 'href', "mailto:$ext_email")
- ->assertSeeIn('.row:nth-child(7) label', 'Address')
- ->assertSeeIn('.row:nth-child(7) #billing_address', $john->getSetting('billing_address'))
- ->assertSeeIn('.row:nth-child(8) label', 'Country')
- ->assertSeeIn('.row:nth-child(8) #country', 'United States of America');
+ ->assertSeeIn('.row:nth-child(5) label', 'Organization')
+ ->assertSeeIn('.row:nth-child(5) #organization', 'Kolab Developers')
+ ->assertSeeIn('.row:nth-child(6) label', 'Phone')
+ ->assertSeeIn('.row:nth-child(6) #phone', $john->getSetting('phone'))
+ ->assertSeeIn('.row:nth-child(7) label', 'External email')
+ ->assertSeeIn('.row:nth-child(7) #external_email a', $ext_email)
+ ->assertAttribute('.row:nth-child(7) #external_email a', 'href', "mailto:$ext_email")
+ ->assertSeeIn('.row:nth-child(8) label', 'Address')
+ ->assertSeeIn('.row:nth-child(8) #billing_address', $john->getSetting('billing_address'))
+ ->assertSeeIn('.row:nth-child(9) label', 'Country')
+ ->assertSeeIn('.row:nth-child(9) #country', 'United States of America');
});
// Some tabs are loaded in background, wait a second
diff --git a/src/tests/Browser/SignupTest.php b/src/tests/Browser/SignupTest.php
--- a/src/tests/Browser/SignupTest.php
+++ b/src/tests/Browser/SignupTest.php
@@ -74,7 +74,8 @@
$code = SignupCode::create([
'data' => [
'email' => 'User@example.org',
- 'name' => 'User Name',
+ 'first_name' => 'User',
+ 'last_name' => 'Name',
'plan' => 'individual',
'voucher' => '',
]
@@ -125,7 +126,7 @@
->assertMissing('@step0')
->assertMissing('@step2')
->assertMissing('@step3')
- ->assertFocused('@step1 #signup_name');
+ ->assertFocused('@step1 #signup_first_name');
// Click Back button
$browser->click('@step1 [type=button]')
@@ -142,7 +143,7 @@
->assertMissing('@step0')
->assertMissing('@step2')
->assertMissing('@step3')
- ->assertFocused('@step1 #signup_name');
+ ->assertFocused('@step1 #signup_first_name');
// TODO: Test if 'plan' variable is set properly in vue component
});
@@ -165,41 +166,44 @@
// Here we expect two text inputs and Back and Continue buttons
$browser->with('@step1', function ($step) {
- $step->assertVisible('#signup_name')
- ->assertFocused('#signup_name')
+ $step->assertVisible('#signup_last_name')
+ ->assertVisible('#signup_first_name')
+ ->assertFocused('#signup_first_name')
->assertVisible('#signup_email')
->assertVisible('[type=button]')
->assertVisible('[type=submit]');
});
// Submit empty form
- // Both Step 1 inputs are required, so after pressing Submit
- // we expect focus to be moved to the first input
+ // Email is required, so after pressing Submit
+ // we expect focus to be moved to the email input
$browser->with('@step1', function ($step) {
$step->click('[type=submit]');
- $step->assertFocused('#signup_name');
+ $step->assertFocused('#signup_email');
});
- // Submit invalid email
- // We expect email input to have is-invalid class added, with .invalid-feedback element
+ // Submit invalid email, and first_name
+ // We expect both inputs to have is-invalid class added, with .invalid-feedback element
$browser->with('@step1', function ($step) use ($browser) {
- $step->type('#signup_name', 'Test User')
+ $step->type('#signup_first_name', str_repeat('a', 250))
->type('#signup_email', '@test')
->click('[type=submit]')
->waitFor('#signup_email.is-invalid')
+ ->assertVisible('#signup_first_name.is-invalid')
->assertVisible('#signup_email + .invalid-feedback')
+ ->assertVisible('#signup_last_name + .invalid-feedback')
->assertToast(Toast::TYPE_ERROR, 'Form validation error');
});
// Submit valid data
// We expect error state on email input to be removed, and Step 2 form visible
$browser->with('@step1', function ($step) {
- $step->type('#signup_name', 'Test User');
- $step->type('#signup_email', 'BrowserSignupTestUser1@kolab.org');
- $step->click('[type=submit]');
-
- $step->assertMissing('#signup_email.is-invalid');
- $step->assertMissing('#signup_email + .invalid-feedback');
+ $step->type('#signup_first_name', 'Test')
+ ->type('#signup_last_name', 'User')
+ ->type('#signup_email', 'BrowserSignupTestUser1@kolab.org')
+ ->click('[type=submit]')
+ ->assertMissing('#signup_email.is-invalid')
+ ->assertMissing('#signup_email + .invalid-feedback');
});
$browser->waitUntilMissing('@step2 #signup_code[value=""]');
@@ -232,14 +236,15 @@
// Test Back button functionality
$browser->click('@step2 [type=button]')
->waitFor('@step1')
- ->assertFocused('@step1 #signup_name')
+ ->assertFocused('@step1 #signup_first_name')
->assertMissing('@step2');
// Submit valid Step 1 data (again)
$browser->with('@step1', function ($step) {
- $step->type('#signup_name', 'Test User');
- $step->type('#signup_email', 'BrowserSignupTestUser1@kolab.org');
- $step->click('[type=submit]');
+ $step->type('#signup_first_name', 'User')
+ ->type('#signup_last_name', 'User')
+ ->type('#signup_email', 'BrowserSignupTestUser1@kolab.org')
+ ->click('[type=submit]');
});
$browser->waitFor('@step2');
@@ -389,7 +394,8 @@
// Submit valid data
// We expect error state on email input to be removed, and Step 2 form visible
$browser->whenAvailable('@step1', function ($step) {
- $step->type('#signup_name', 'Test User')
+ $step->type('#signup_first_name', 'Test')
+ ->type('#signup_last_name', 'User')
->type('#signup_email', 'BrowserSignupTestUser1@kolab.org')
->click('[type=submit]');
});
@@ -478,7 +484,8 @@
->waitFor('@step0')
->click('.plan-individual button')
->whenAvailable('@step1', function (Browser $browser) {
- $browser->type('#signup_name', 'Test User')
+ $browser->type('#signup_first_name', 'Test')
+ ->type('#signup_last_name', 'User')
->type('#signup_email', 'BrowserSignupTestUser1@kolab.org')
->click('[type=submit]');
})
diff --git a/src/tests/Browser/UserProfileTest.php b/src/tests/Browser/UserProfileTest.php
--- a/src/tests/Browser/UserProfileTest.php
+++ b/src/tests/Browser/UserProfileTest.php
@@ -21,6 +21,7 @@
'billing_address' => "601 13th Street NW\nSuite 900 South\nWashington, DC 20005",
'external_email' => 'john.doe.external@gmail.com',
'phone' => '+1 509-248-1111',
+ 'organization' => 'Kolab Developers',
];
/**
@@ -76,24 +77,27 @@
->assertValue('div.row:nth-child(1) input[type=text]', $this->profile['first_name'])
->assertSeeIn('div.row:nth-child(2) label', 'Last name')
->assertValue('div.row:nth-child(2) input[type=text]', $this->profile['last_name'])
- ->assertSeeIn('div.row:nth-child(3) label', 'Phone')
- ->assertValue('div.row:nth-child(3) input[type=text]', $this->profile['phone'])
- ->assertSeeIn('div.row:nth-child(4) label', 'External email')
- ->assertValue('div.row:nth-child(4) input[type=text]', $this->profile['external_email'])
- ->assertSeeIn('div.row:nth-child(5) label', 'Address')
- ->assertValue('div.row:nth-child(5) textarea', $this->profile['billing_address'])
- ->assertSeeIn('div.row:nth-child(6) label', 'Country')
- ->assertValue('div.row:nth-child(6) select', $this->profile['country'])
- ->assertSeeIn('div.row:nth-child(7) label', 'Password')
- ->assertValue('div.row:nth-child(7) input[type=password]', '')
- ->assertSeeIn('div.row:nth-child(8) label', 'Confirm password')
+ ->assertSeeIn('div.row:nth-child(3) label', 'Organization')
+ ->assertValue('div.row:nth-child(3) input[type=text]', $this->profile['organization'])
+ ->assertSeeIn('div.row:nth-child(4) label', 'Phone')
+ ->assertValue('div.row:nth-child(4) input[type=text]', $this->profile['phone'])
+ ->assertSeeIn('div.row:nth-child(5) label', 'External email')
+ ->assertValue('div.row:nth-child(5) input[type=text]', $this->profile['external_email'])
+ ->assertSeeIn('div.row:nth-child(6) label', 'Address')
+ ->assertValue('div.row:nth-child(6) textarea', $this->profile['billing_address'])
+ ->assertSeeIn('div.row:nth-child(7) label', 'Country')
+ ->assertValue('div.row:nth-child(7) select', $this->profile['country'])
+ ->assertSeeIn('div.row:nth-child(8) label', 'Password')
->assertValue('div.row:nth-child(8) input[type=password]', '')
+ ->assertSeeIn('div.row:nth-child(9) label', 'Confirm password')
+ ->assertValue('div.row:nth-child(9) input[type=password]', '')
->assertSeeIn('button[type=submit]', 'Submit');
// Clear all fields and submit
// FIXME: Should any of these fields be required?
$browser->type('#first_name', '')
->type('#last_name', '')
+ ->type('#organization', '')
->type('#phone', '')
->type('#external_email', '')
->type('#billing_address', '')
diff --git a/src/tests/Browser/UsersTest.php b/src/tests/Browser/UsersTest.php
--- a/src/tests/Browser/UsersTest.php
+++ b/src/tests/Browser/UsersTest.php
@@ -24,6 +24,7 @@
private $profile = [
'first_name' => 'John',
'last_name' => 'Doe',
+ 'organization' => 'Kolab Developers',
];
/**
@@ -140,19 +141,21 @@
->assertValue('div.row:nth-child(2) input[type=text]', $this->profile['first_name'])
->assertSeeIn('div.row:nth-child(3) label', 'Last name')
->assertValue('div.row:nth-child(3) input[type=text]', $this->profile['last_name'])
- ->assertSeeIn('div.row:nth-child(4) label', 'Email')
- ->assertValue('div.row:nth-child(4) input[type=text]', 'john@kolab.org')
- ->assertDisabled('div.row:nth-child(4) input[type=text]')
- ->assertSeeIn('div.row:nth-child(5) label', 'Email aliases')
- ->assertVisible('div.row:nth-child(5) .list-input')
+ ->assertSeeIn('div.row:nth-child(4) label', 'Organization')
+ ->assertValue('div.row:nth-child(4) input[type=text]', $this->profile['organization'])
+ ->assertSeeIn('div.row:nth-child(5) label', 'Email')
+ ->assertValue('div.row:nth-child(5) input[type=text]', 'john@kolab.org')
+ ->assertDisabled('div.row:nth-child(5) input[type=text]')
+ ->assertSeeIn('div.row:nth-child(6) label', 'Email aliases')
+ ->assertVisible('div.row:nth-child(6) .list-input')
->with(new ListInput('#aliases'), function (Browser $browser) {
$browser->assertListInputValue(['john.doe@kolab.org'])
->assertValue('@input', '');
})
- ->assertSeeIn('div.row:nth-child(6) label', 'Password')
- ->assertValue('div.row:nth-child(6) input[type=password]', '')
- ->assertSeeIn('div.row:nth-child(7) label', 'Confirm password')
+ ->assertSeeIn('div.row:nth-child(7) label', 'Password')
->assertValue('div.row:nth-child(7) input[type=password]', '')
+ ->assertSeeIn('div.row:nth-child(8) label', 'Confirm password')
+ ->assertValue('div.row:nth-child(8) input[type=password]', '')
->assertSeeIn('button[type=submit]', 'Submit');
// Clear some fields and submit
@@ -210,8 +213,8 @@
// Test subscriptions
$browser->with('@form', function (Browser $browser) {
- $browser->assertSeeIn('div.row:nth-child(8) label', 'Subscriptions')
- ->assertVisible('@skus.row:nth-child(8)')
+ $browser->assertSeeIn('div.row:nth-child(9) label', 'Subscriptions')
+ ->assertVisible('@skus.row:nth-child(9)')
->with('@skus', function ($browser) {
$browser->assertElementsCount('tbody tr', 5)
// Mailbox SKU
@@ -321,20 +324,22 @@
->assertValue('div.row:nth-child(1) input[type=text]', '')
->assertSeeIn('div.row:nth-child(2) label', 'Last name')
->assertValue('div.row:nth-child(2) input[type=text]', '')
- ->assertSeeIn('div.row:nth-child(3) label', 'Email')
+ ->assertSeeIn('div.row:nth-child(3) label', 'Organization')
->assertValue('div.row:nth-child(3) input[type=text]', '')
- ->assertEnabled('div.row:nth-child(3) input[type=text]')
- ->assertSeeIn('div.row:nth-child(4) label', 'Email aliases')
- ->assertVisible('div.row:nth-child(4) .list-input')
+ ->assertSeeIn('div.row:nth-child(4) label', 'Email')
+ ->assertValue('div.row:nth-child(4) input[type=text]', '')
+ ->assertEnabled('div.row:nth-child(4) input[type=text]')
+ ->assertSeeIn('div.row:nth-child(5) label', 'Email aliases')
+ ->assertVisible('div.row:nth-child(5) .list-input')
->with(new ListInput('#aliases'), function (Browser $browser) {
$browser->assertListInputValue([])
->assertValue('@input', '');
})
- ->assertSeeIn('div.row:nth-child(5) label', 'Password')
- ->assertValue('div.row:nth-child(5) input[type=password]', '')
- ->assertSeeIn('div.row:nth-child(6) label', 'Confirm password')
+ ->assertSeeIn('div.row:nth-child(6) label', 'Password')
->assertValue('div.row:nth-child(6) input[type=password]', '')
- ->assertSeeIn('div.row:nth-child(7) label', 'Package')
+ ->assertSeeIn('div.row:nth-child(7) label', 'Confirm password')
+ ->assertValue('div.row:nth-child(7) input[type=password]', '')
+ ->assertSeeIn('div.row:nth-child(8) label', 'Package')
// assert packages list widget, select "Lite Account"
->with('@packages', function ($browser) {
$browser->assertElementsCount('tbody tr', 2)
@@ -382,10 +387,13 @@
// Successful account creation
$browser->with('@form', function (Browser $browser) {
- $browser->with(new ListInput('#aliases'), function (Browser $browser) {
- $browser->removeListEntry(1)
- ->addListEntry('julia.roberts2@kolab.org');
- })
+ $browser->type('#first_name', 'Julia')
+ ->type('#last_name', 'Roberts')
+ ->type('#organization', 'Test Org')
+ ->with(new ListInput('#aliases'), function (Browser $browser) {
+ $browser->removeListEntry(1)
+ ->addListEntry('julia.roberts2@kolab.org');
+ })
->click('button[type=submit]');
})
->assertToast(Toast::TYPE_SUCCESS, 'User created successfully.')
@@ -401,6 +409,9 @@
$alias = UserAlias::where('user_id', $julia->id)->where('alias', 'julia.roberts2@kolab.org')->first();
$this->assertTrue(!empty($alias));
$this->assertUserEntitlements($julia, ['mailbox', 'storage', 'storage']);
+ $this->assertSame('Julia', $julia->getSetting('first_name'));
+ $this->assertSame('Roberts', $julia->getSetting('last_name'));
+ $this->assertSame('Test Org', $julia->getSetting('organization'));
});
}
diff --git a/src/tests/Feature/Backends/LDAPTest.php b/src/tests/Feature/Backends/LDAPTest.php
--- a/src/tests/Feature/Backends/LDAPTest.php
+++ b/src/tests/Feature/Backends/LDAPTest.php
@@ -4,48 +4,151 @@
use App\Backends\LDAP;
use App\Domain;
+use App\Entitlement;
use App\User;
+use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
class LDAPTest extends TestCase
{
/**
- * Test creating a domain record
- *
- * @group ldap
+ * {@inheritDoc}
*/
- public function testCreateDomain(): void
+ public function setUp(): void
{
- $this->markTestIncomplete();
+ parent::setUp();
+
+ $this->deleteTestUser('user-ldap-test@' . \config('app.domain'));
}
/**
- * Test creating a user record
- *
- * @group ldap
+ * {@inheritDoc}
*/
- public function testCreateUser(): void
+ public function tearDown(): void
{
- $this->markTestIncomplete();
+ $this->deleteTestUser('user-ldap-test@' . \config('app.domain'));
+
+ parent::tearDown();
}
/**
- * Test updating a domain record
+ * Test creating/updating/deleting a domain record
*
* @group ldap
*/
- public function testUpdateDomain(): void
+ public function testDomain(): void
{
$this->markTestIncomplete();
}
/**
- * Test updating a user record
+ * Test creating/editing/deleting a user record
*
* @group ldap
*/
- public function testUpdateUser(): void
+ public function testUser(): void
{
- $this->markTestIncomplete();
+ Queue::fake();
+
+ $user = $this->getTestUser('user-ldap-test@' . \config('app.domain'));
+
+ LDAP::createUser($user);
+
+ $ldap_user = LDAP::getUser($user->email);
+
+ $expected = [
+ 'objectclass' => [
+ 'top',
+ 'inetorgperson',
+ 'inetuser',
+ 'kolabinetorgperson',
+ 'mailrecipient',
+ 'person',
+ 'organizationalPerson',
+ ],
+ 'mail' => $user->email,
+ 'uid' => $user->email,
+ 'nsroledn' => null,
+ 'cn' => 'unknown',
+ 'displayname' => '',
+ 'givenname' => '',
+ 'sn' => 'unknown',
+ 'inetuserstatus' => $user->status,
+ 'mailquota' => null,
+ 'o' => '',
+ 'alias' => null,
+ ];
+
+ foreach ($expected as $attr => $value) {
+ $this->assertEquals($value, isset($ldap_user[$attr]) ? $ldap_user[$attr] : null);
+ }
+
+ // Add aliases, and change some user settings, and entitlements
+ $user->setSettings([
+ 'first_name' => 'Firstname',
+ 'last_name' => 'Lastname',
+ 'organization' => 'Org',
+ 'country' => 'PL',
+ ]);
+ $user->status |= User::STATUS_IMAP_READY;
+ $user->save();
+ $aliases = ['t1-' . $user->email, 't2-' . $user->email];
+ $user->setAliases($aliases);
+ $package_kolab = \App\Package::where('title', 'kolab')->first();
+ $user->assignPackage($package_kolab);
+
+ LDAP::updateUser($user->fresh());
+
+ $expected['alias'] = $aliases;
+ $expected['o'] = 'Org';
+ $expected['displayname'] = 'Lastname, Firstname';
+ $expected['givenname'] = 'Firstname';
+ $expected['cn'] = 'Firstname Lastname';
+ $expected['sn'] = 'Lastname';
+ $expected['inetuserstatus'] = $user->status;
+ $expected['mailquota'] = 2097152;
+ $expected['nsroledn'] = null;
+ // TODO: country? dn
+
+ $ldap_user = LDAP::getUser($user->email);
+
+ foreach ($expected as $attr => $value) {
+ $this->assertEquals($value, isset($ldap_user[$attr]) ? $ldap_user[$attr] : null);
+ }
+
+ // Update entitlements
+ $sku_activesync = \App\Sku::where('title', 'activesync')->first();
+ $sku_groupware = \App\Sku::where('title', 'groupware')->first();
+ $user->assignSku($sku_activesync, 1);
+ Entitlement::where(['sku_id' => $sku_groupware->id, 'entitleable_id' => $user->id])->delete();
+
+ LDAP::updateUser($user->fresh());
+
+ $expected_roles = [
+ 'activesync-user',
+ 'imap-user'
+ ];
+
+ $ldap_user = LDAP::getUser($user->email);
+
+ $this->assertCount(2, $ldap_user['nsroledn']);
+
+ $ldap_roles = array_map(
+ function ($role) {
+ if (preg_match('/^cn=([a-z0-9-]+)/', $role, $m)) {
+ return $m[1];
+ } else {
+ return $role;
+ }
+ },
+ $ldap_user['nsroledn']
+ );
+
+ $this->assertSame($expected_roles, $ldap_roles);
+
+ // Delete the user
+ LDAP::deleteUser($user);
+
+ $this->assertSame(null, LDAP::getUser($user->email));
}
}
diff --git a/src/tests/Feature/Controller/SignupTest.php b/src/tests/Feature/Controller/SignupTest.php
--- a/src/tests/Feature/Controller/SignupTest.php
+++ b/src/tests/Feature/Controller/SignupTest.php
@@ -107,13 +107,14 @@
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
- $this->assertCount(2, $json['errors']);
+ $this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('email', $json['errors']);
- $this->assertArrayHasKey('name', $json['errors']);
// Data with missing name
$data = [
'email' => 'UsersApiControllerTest1@UsersApiControllerTest.com',
+ 'first_name' => str_repeat('a', 250),
+ 'last_name' => str_repeat('a', 250),
];
$response = $this->post('/api/auth/signup/init', $data);
@@ -122,13 +123,15 @@
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
- $this->assertCount(1, $json['errors']);
- $this->assertArrayHasKey('name', $json['errors']);
+ $this->assertCount(2, $json['errors']);
+ $this->assertArrayHasKey('first_name', $json['errors']);
+ $this->assertArrayHasKey('last_name', $json['errors']);
// Data with invalid email (but not phone number)
$data = [
'email' => '@example.org',
- 'name' => 'Signup User',
+ 'first_name' => 'Signup',
+ 'last_name' => 'User',
];
$response = $this->post('/api/auth/signup/init', $data);
@@ -140,10 +143,9 @@
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('email', $json['errors']);
- // Sanity check on voucher code
+ // Sanity check on voucher code, last/first name is optional
$data = [
'voucher' => '123456789012345678901234567890123',
- 'name' => 'Signup User',
'email' => 'valid@email.com',
];
@@ -173,7 +175,8 @@
$data = [
'email' => 'testuser@external.com',
- 'name' => 'Signup User',
+ 'first_name' => 'Signup',
+ 'last_name' => 'User',
'plan' => 'individual',
];
@@ -195,7 +198,8 @@
return $code->code === $json['code']
&& $code->data['plan'] === $data['plan']
&& $code->data['email'] === $data['email']
- && $code->data['name'] === $data['name'];
+ && $code->data['first_name'] === $data['first_name']
+ && $code->data['last_name'] === $data['last_name'];
});
// Try the same with voucher
@@ -217,13 +221,15 @@
&& $code->data['plan'] === $data['plan']
&& $code->data['email'] === $data['email']
&& $code->data['voucher'] === $data['voucher']
- && $code->data['name'] === $data['name'];
+ && $code->data['first_name'] === $data['first_name']
+ && $code->data['last_name'] === $data['last_name'];
});
return [
'code' => $json['code'],
'email' => $data['email'],
- 'name' => $data['name'],
+ 'first_name' => $data['first_name'],
+ 'last_name' => $data['last_name'],
'plan' => $data['plan'],
'voucher' => $data['voucher']
];
@@ -298,10 +304,11 @@
$json = $response->json();
$response->assertStatus(200);
- $this->assertCount(6, $json);
+ $this->assertCount(7, $json);
$this->assertSame('success', $json['status']);
$this->assertSame($result['email'], $json['email']);
- $this->assertSame($result['name'], $json['name']);
+ $this->assertSame($result['first_name'], $json['first_name']);
+ $this->assertSame($result['last_name'], $json['last_name']);
$this->assertSame($result['voucher'], $json['voucher']);
$this->assertSame(false, $json['is_domain']);
$this->assertTrue(is_array($json['domains']) && !empty($json['domains']));
@@ -489,9 +496,10 @@
$this->assertNotEmpty($user);
$this->assertSame($identity, $user->email);
- $this->assertSame($result['name'], $user->name);
- // Check external email in user settings
+ // Check user settings
+ $this->assertSame($result['first_name'], $user->getSetting('first_name'));
+ $this->assertSame($result['last_name'], $user->getSetting('last_name'));
$this->assertSame($result['email'], $user->getSetting('external_email'));
// Discount
@@ -515,7 +523,8 @@
// Initial signup request
$user_data = $data = [
'email' => 'testuser@external.com',
- 'name' => 'Signup User',
+ 'first_name' => 'Signup',
+ 'last_name' => 'User',
'plan' => 'group',
];
@@ -537,7 +546,8 @@
return $code->code === $json['code']
&& $code->data['plan'] === $data['plan']
&& $code->data['email'] === $data['email']
- && $code->data['name'] === $data['name'];
+ && $code->data['first_name'] === $data['first_name']
+ && $code->data['last_name'] === $data['last_name'];
});
// Verify the code
@@ -551,10 +561,11 @@
$result = $response->json();
$response->assertStatus(200);
- $this->assertCount(6, $result);
+ $this->assertCount(7, $result);
$this->assertSame('success', $result['status']);
$this->assertSame($user_data['email'], $result['email']);
- $this->assertSame($user_data['name'], $result['name']);
+ $this->assertSame($user_data['first_name'], $result['first_name']);
+ $this->assertSame($user_data['last_name'], $result['last_name']);
$this->assertSame(null, $result['voucher']);
$this->assertSame(true, $result['is_domain']);
$this->assertSame([], $result['domains']);
@@ -602,12 +613,13 @@
$user = User::where('email', $login . '@' . $domain)->first();
$this->assertNotEmpty($user);
- $this->assertSame($user_data['name'], $user->name);
-
- // Check domain record
- // Check external email in user settings
+ // Check user settings
$this->assertSame($user_data['email'], $user->getSetting('external_email'));
+ $this->assertSame($user_data['first_name'], $user->getSetting('first_name'));
+ $this->assertSame($user_data['last_name'], $user->getSetting('last_name'));
+
+ // TODO: Check domain record
// TODO: Check SKUs/Plan
diff --git a/src/tests/Feature/Controller/UsersTest.php b/src/tests/Feature/Controller/UsersTest.php
--- a/src/tests/Feature/Controller/UsersTest.php
+++ b/src/tests/Feature/Controller/UsersTest.php
@@ -139,7 +139,7 @@
// TODO/FIXME:
// For now controller can delete himself, as well as
// the whole account he has control to, including the owner
- // Probably he should not be able to do either of those
+ // Probably he should not be able to do none of those
// However, this is not 0-regression scenario as we
// do not fully support additional controllers.
@@ -290,6 +290,7 @@
$this->assertTrue(is_array($result['settings']));
$this->assertSame('US', $result['settings']['country']);
$this->assertSame('USD', $result['settings']['currency']);
+ // TODO: Test all settings
$this->assertTrue(is_array($result['accounts']));
$this->assertTrue(is_array($result['wallets']));
@@ -460,6 +461,7 @@
'first_name' => 'John2',
'last_name' => 'Doe2',
'email' => 'john2.doe2@kolab.org',
+ 'organization' => 'TestOrg',
'aliases' => ['useralias1@kolab.org', 'useralias2@kolab.org'],
];
@@ -499,6 +501,7 @@
$this->assertInstanceOf(User::class, $user);
$this->assertSame('John2', $user->getSetting('first_name'));
$this->assertSame('Doe2', $user->getSetting('last_name'));
+ $this->assertSame('TestOrg', $user->getSetting('organization'));
$aliases = $user->aliases()->orderBy('alias')->get();
$this->assertCount(2, $aliases);
$this->assertSame('useralias1@kolab.org', $aliases[0]->alias);
@@ -575,6 +578,7 @@
'password_confirmation' => 'simple',
'first_name' => 'John2',
'last_name' => 'Doe2',
+ 'organization' => 'TestOrg',
'phone' => '+123 123 123',
'external_email' => 'external@gmail.com',
'billing_address' => 'billing',
@@ -605,6 +609,7 @@
$post = [
'first_name' => '',
'last_name' => '',
+ 'organization' => '',
'phone' => '',
'external_email' => '',
'billing_address' => '',
diff --git a/src/tests/Feature/Jobs/SignupVerificationEmailTest.php b/src/tests/Feature/Jobs/SignupVerificationEmailTest.php
--- a/src/tests/Feature/Jobs/SignupVerificationEmailTest.php
+++ b/src/tests/Feature/Jobs/SignupVerificationEmailTest.php
@@ -24,7 +24,8 @@
$this->code = SignupCode::create([
'data' => [
'email' => 'SignupVerificationEmailTest1@' . \config('app.domain'),
- 'name' => "Test Job"
+ 'first_name' => "Test",
+ 'last_name' => "Job"
]
]);
}
diff --git a/src/tests/Feature/Jobs/UserVerifyTest.php b/src/tests/Feature/Jobs/UserVerifyTest.php
--- a/src/tests/Feature/Jobs/UserVerifyTest.php
+++ b/src/tests/Feature/Jobs/UserVerifyTest.php
@@ -14,12 +14,16 @@
{
parent::setUp();
- $this->deleteTestUser('jane@kolabnow.com');
+ $ned = $this->getTestUser('ned@kolab.org');
+ $ned->status |= User::STATUS_IMAP_READY;
+ $ned->save();
}
public function tearDown(): void
{
- $this->deleteTestUser('jane@kolabnow.com');
+ $ned = $this->getTestUser('ned@kolab.org');
+ $ned->status |= User::STATUS_IMAP_READY;
+ $ned->save();
parent::tearDown();
}
@@ -33,17 +37,11 @@
{
Queue::fake();
- $user = $this->getTestUser('jane@kolabnow.com');
+ $user = $this->getTestUser('ned@kolab.org');
+ $user->status ^= User::STATUS_IMAP_READY;
+ $user->save();
- // This is a valid assertion in a feature, not functional test environment.
$this->assertFalse($user->isImapReady());
- $this->assertFalse($user->isLdapReady());
-
- $job = new UserCreate($user);
- $job->handle();
-
- $this->assertFalse($user->isImapReady());
- $this->assertTrue($user->isLdapReady());
for ($i = 0; $i < 10; $i++) {
$job = new UserVerify($user);
diff --git a/src/tests/Feature/UserTest.php b/src/tests/Feature/UserTest.php
--- a/src/tests/Feature/UserTest.php
+++ b/src/tests/Feature/UserTest.php
@@ -13,8 +13,7 @@
{
parent::setUp();
- $this->deleteTestUser('user-create-test@' . \config('app.domain'));
- $this->deleteTestUser('userdeletejob@kolabnow.com');
+ $this->deleteTestUser('user-test@' . \config('app.domain'));
$this->deleteTestUser('UserAccountA@UserAccount.com');
$this->deleteTestUser('UserAccountB@UserAccount.com');
$this->deleteTestUser('UserAccountC@UserAccount.com');
@@ -23,8 +22,7 @@
public function tearDown(): void
{
- $this->deleteTestUser('user-create-test@' . \config('app.domain'));
- $this->deleteTestUser('userdeletejob@kolabnow.com');
+ $this->deleteTestUser('user-test@' . \config('app.domain'));
$this->deleteTestUser('UserAccountA@UserAccount.com');
$this->deleteTestUser('UserAccountB@UserAccount.com');
$this->deleteTestUser('UserAccountC@UserAccount.com');
@@ -67,7 +65,7 @@
Queue::assertNothingPushed();
$user = User::create([
- 'email' => 'user-create-test@' . \config('app.domain')
+ 'email' => 'user-test@' . \config('app.domain')
]);
Queue::assertPushed(\App\Jobs\UserCreate::class, 1);
@@ -191,7 +189,7 @@
{
Queue::fake();
- $user = $this->getTestUser('userdeletejob@kolabnow.com');
+ $user = $this->getTestUser('user-test@' . \config('app.domain'));
$package = \App\Package::where('title', 'kolab')->first();
$user->assignPackage($package);
@@ -287,6 +285,29 @@
}
/**
+ * Test User::name()
+ */
+ public function testName(): void
+ {
+ Queue::fake();
+
+ $user = $this->getTestUser('user-test@' . \config('app.domain'));
+
+ $this->assertSame('', $user->name());
+ $this->assertSame(\config('app.name') . ' User', $user->name(true));
+
+ $user->setSetting('first_name', 'First');
+
+ $this->assertSame('First', $user->name());
+ $this->assertSame('First', $user->name(true));
+
+ $user->setSetting('last_name', 'Last');
+
+ $this->assertSame('First Last', $user->name());
+ $this->assertSame('First Last', $user->name(true));
+ }
+
+ /**
* Tests for UserAliasesTrait::setAliases()
*/
public function testSetAliases(): void
@@ -335,11 +356,88 @@
}
/**
- * Tests for UserSettingsTrait::setSettings()
+ * Tests for UserSettingsTrait::setSettings() and getSetting()
*/
- public function testSetSettings(): void
+ public function testUserSettings(): void
{
- $this->markTestIncomplete();
+ Queue::fake();
+ Queue::assertNothingPushed();
+
+ $user = $this->getTestUser('UserAccountA@UserAccount.com');
+
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 0);
+
+ // Test default settings
+ // Note: Technicly this tests UserObserver::created() behavior
+ $all_settings = $user->settings()->orderBy('key')->get();
+ $this->assertCount(2, $all_settings);
+ $this->assertSame('country', $all_settings[0]->key);
+ $this->assertSame('CH', $all_settings[0]->value);
+ $this->assertSame('currency', $all_settings[1]->key);
+ $this->assertSame('CHF', $all_settings[1]->value);
+
+ // Add a setting
+ $user->setSetting('first_name', 'Firstname');
+
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 1);
+
+ // Note: We test both current user as well as fresh user object
+ // to make sure cache works as expected
+ $this->assertSame('Firstname', $user->getSetting('first_name'));
+ $this->assertSame('Firstname', $user->fresh()->getSetting('first_name'));
+
+ // Update a setting
+ $user->setSetting('first_name', 'Firstname1');
+
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 2);
+
+ // Note: We test both current user as well as fresh user object
+ // to make sure cache works as expected
+ $this->assertSame('Firstname1', $user->getSetting('first_name'));
+ $this->assertSame('Firstname1', $user->fresh()->getSetting('first_name'));
+
+ // Delete a setting (null)
+ $user->setSetting('first_name', null);
+
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 3);
+
+ // Note: We test both current user as well as fresh user object
+ // to make sure cache works as expected
+ $this->assertSame(null, $user->getSetting('first_name'));
+ $this->assertSame(null, $user->fresh()->getSetting('first_name'));
+
+ // Delete a setting (empty string)
+ $user->setSetting('first_name', 'Firstname1');
+ $user->setSetting('first_name', '');
+
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 5);
+
+ // Note: We test both current user as well as fresh user object
+ // to make sure cache works as expected
+ $this->assertSame(null, $user->getSetting('first_name'));
+ $this->assertSame(null, $user->fresh()->getSetting('first_name'));
+
+ // Set multiple settings at once
+ $user->setSettings([
+ 'first_name' => 'Firstname2',
+ 'last_name' => 'Lastname2',
+ 'country' => null,
+ ]);
+
+ // TODO: This really should create a single UserUpdate job, not 3
+ Queue::assertPushed(\App\Jobs\UserUpdate::class, 7);
+
+ // Note: We test both current user as well as fresh user object
+ // to make sure cache works as expected
+ $this->assertSame('Firstname2', $user->getSetting('first_name'));
+ $this->assertSame('Firstname2', $user->fresh()->getSetting('first_name'));
+ $this->assertSame('Lastname2', $user->getSetting('last_name'));
+ $this->assertSame('Lastname2', $user->fresh()->getSetting('last_name'));
+ $this->assertSame(null, $user->getSetting('country'));
+ $this->assertSame(null, $user->fresh()->getSetting('country'));
+
+ $all_settings = $user->settings()->orderBy('key')->get();
+ $this->assertCount(3, $all_settings);
}
/**
diff --git a/src/tests/TestCase.php b/src/tests/TestCase.php
--- a/src/tests/TestCase.php
+++ b/src/tests/TestCase.php
@@ -26,5 +26,6 @@
// If we wanted to access both user and admin in one test
// we can also just call post/get/whatever with full url
\config(['app.url' => str_replace('//', '//admin.', \config('app.url'))]);
+ url()->forceRootUrl(config('app.url'));
}
}
diff --git a/src/tests/Unit/Mail/PasswordResetTest.php b/src/tests/Unit/Mail/PasswordResetTest.php
--- a/src/tests/Unit/Mail/PasswordResetTest.php
+++ b/src/tests/Unit/Mail/PasswordResetTest.php
@@ -35,6 +35,6 @@
$this->assertSame(\config('app.name') . ' Password Reset', $mail->subject);
$this->assertStringStartsWith('<!DOCTYPE html>', $html);
$this->assertTrue(strpos($html, $link) > 0);
- $this->assertTrue(strpos($html, $code->user->name) > 0);
+ $this->assertTrue(strpos($html, $code->user->name(true)) > 0);
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 12:16 PM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18778263
Default Alt Text
D1213.1774873000.diff (65 KB)

Event Timeline