diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php index 3515f6b7..c8907ea7 100644 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ b/app/Actions/Fortify/UpdateUserProfileInformation.php @@ -20,6 +20,7 @@ public function update($user, array $input) { Validator::make($input, [ 'first_name' => ['required', 'string', 'max:255'], + 'name' => ['nullable', 'string', 'max:255'], 'last_name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)], 'username' => ['required', 'string', 'max:255', Rule::unique('users')->ignore($user->id)], @@ -38,6 +39,7 @@ public function update($user, array $input) 'first_name' => $input['first_name'], 'last_name' => $input['last_name'], 'username' => $input['username'], + 'name' => $input['username'] ? $input['username'] : $user->name, 'email' => $input['email'], ])->save(); } @@ -55,6 +57,7 @@ protected function updateVerifiedUser($user, array $input) $user->forceFill([ 'first_name' => $input['first_name'], 'last_name' => $input['last_name'], + 'name' => $input['name'] ? $input['name'] : $user->name, 'username' => $input['username'], 'email' => $input['email'], 'email_verified_at' => null, diff --git a/app/Actions/Project/UpdateProject.php b/app/Actions/Project/UpdateProject.php index ef5d253d..ba247ab1 100644 --- a/app/Actions/Project/UpdateProject.php +++ b/app/Actions/Project/UpdateProject.php @@ -126,7 +126,7 @@ public function update(Project $project, array $input) $draft = $project->draft; - if($draft){ + if ($draft) { $draft->name = $project->name; $draft->slug = $project->slug; $draft->description = $project->description; diff --git a/app/Console/Commands/AssignIdentifiers.php b/app/Console/Commands/AssignIdentifiers.php index 3d51fd19..80f46ecb 100644 --- a/app/Console/Commands/AssignIdentifiers.php +++ b/app/Console/Commands/AssignIdentifiers.php @@ -33,7 +33,7 @@ public function handle(DOIService $doiService) { return DB::transaction(function () use ($doiService) { $projects = Project::where([ - ['is_public', true] + ['is_public', true], ])->get(); foreach ($projects as $project) { $projectIdentifier = $project->identifier ? $project->identifier : null; diff --git a/app/Http/Controllers/DatasetController.php b/app/Http/Controllers/DatasetController.php index 0ae324e4..b7456979 100644 --- a/app/Http/Controllers/DatasetController.php +++ b/app/Http/Controllers/DatasetController.php @@ -46,6 +46,7 @@ public function nmriumInfo(Request $request, Dataset $dataset) $nmriumInfo = $spectra; $molecules = $request->get('molecules'); $molecularInfo = $molecules; + $version = $request->get('version'); $nmrium = $dataset->nmrium; if ($nmrium) { @@ -60,6 +61,10 @@ public function nmriumInfo(Request $request, Dataset $dataset) $nmriumData['molecules'] = $molecularInfo; } + if ($version && ! empty($version)) { + $nmriumData['version'] = $version; + } + if (! empty($nmriumData)) { if ($nmrium) { $nmrium->nmrium_info = $nmriumData; diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index eea1cd32..bc294e78 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -4,6 +4,7 @@ use App\Models\Announcement; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Schema; use Inertia\Middleware; class HandleInertiaRequests extends Middleware @@ -61,7 +62,7 @@ public function share(Request $request) 'twitter' => (env('TWITTER_CLIENT_ID') !== null && env('TWITTER_CLIENT_ID') !== ''), 'github' => (env('GITHUB_CLIENT_ID') !== null && env('GITHUB_CLIENT_ID') !== ''), 'orcid' => (env('ORCID_CLIENT_ID') !== null && env('ORCID_CLIENT_ID') !== ''), - 'config.announcements' => Announcement::active(), + 'config.announcements' => Schema::hasTable('announcements') ? Announcement::active() : null, 'url' => env('APP_URL'), 'nmriumURL' => env('NMRIUM_URL'), 'team' => $user ? $user->currentTeam : null, diff --git a/app/Providers/JetstreamServiceProvider.php b/app/Providers/JetstreamServiceProvider.php index aa8cc34d..87969025 100644 --- a/app/Providers/JetstreamServiceProvider.php +++ b/app/Providers/JetstreamServiceProvider.php @@ -49,7 +49,7 @@ public function boot() */ protected function configurePermissions() { - Jetstream::defaultApiTokenPermissions(['read']); + Jetstream::defaultApiTokenPermissions(['project:read']); Jetstream::role('owner', 'Owner', [ 'project:create', diff --git a/composer.json b/composer.json index deee39b6..df79777c 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "tightenco/ziggy": "^1.0" }, "require-dev": { + "brianium/paratest": "^6.6", "fakerphp/faker": "^1.9.1", "laravel/pint": "^1.0", "laravel/sail": "^1.15", diff --git a/composer.lock b/composer.lock index 61a4bf0e..4675fdb4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "376514ae2c6a9e733e8243996fb4f7d1", + "content-hash": "0717bd4c167a383a7cda8e41ce7ac20f", "packages": [ { "name": "asm89/stack-cors", @@ -8967,6 +8967,99 @@ } ], "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v6.6.3", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "f2d781bb9136cda2f5e73ee778049e80ba681cf6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/f2d781bb9136cda2f5e73ee778049e80ba681cf6", + "reference": "f2d781bb9136cda2f5e73ee778049e80ba681cf6", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "jean85/pretty-package-versions": "^2.0.5", + "php": "^7.3 || ^8.0", + "phpunit/php-code-coverage": "^9.2.16", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-timer": "^5.0.3", + "phpunit/phpunit": "^9.5.23", + "sebastian/environment": "^5.1.4", + "symfony/console": "^5.4.9 || ^6.1.2", + "symfony/polyfill-php80": "^v1.26.0", + "symfony/process": "^5.4.8 || ^6.1.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "infection/infection": "^0.26.13", + "malukenho/mcbumpface": "^1.1.5", + "squizlabs/php_codesniffer": "^3.7.1", + "symfony/filesystem": "^5.4.9 || ^6.1.0", + "vimeo/psalm": "^4.26.0" + }, + "bin": [ + "bin/paratest", + "bin/paratest.bat", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v6.6.3" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2022-08-25T05:44:14+00:00" + }, { "name": "doctrine/instantiator", "version": "1.4.1", @@ -9226,6 +9319,65 @@ }, "time": "2020-07-09T08:09:16+00:00" }, + { + "name": "jean85/pretty-package-versions", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.17", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^0.12.66", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.5" + }, + "time": "2021-10-08T21:21:46+00:00" + }, { "name": "laravel/pint", "version": "v1.1.1", diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 87058985..1453066c 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -26,8 +26,11 @@ public function definition() { return [ 'name' => $this->faker->name(), + 'first_name' => $this->faker->firstName(), + 'last_name' => $this->faker->lastName(), 'email' => $this->faker->unique()->safeEmail(), 'email_verified_at' => now(), + 'username' => $this->faker->userName(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), ]; diff --git a/phpunit.xml b/phpunit.xml index da0c7b9d..d3d3f4c7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -21,8 +21,8 @@ - - + + diff --git a/resources/js/Shared/SpectraEditor.vue b/resources/js/Shared/SpectraEditor.vue index 07469428..af7de25a 100644 --- a/resources/js/Shared/SpectraEditor.vue +++ b/resources/js/Shared/SpectraEditor.vue @@ -363,6 +363,7 @@ export default { currentMolecules: [], reset: false, info: null, + version: null, }; }, computed: { @@ -395,6 +396,7 @@ export default { this.saveStudyPreview(e.data.data.data); } } + this.version = e.data.data.version; if (e.data.type == "nmr-wrapper:data-change") { let actionType = e.data.data.actionType; // console.log(actionType); @@ -479,6 +481,10 @@ export default { if (spectra && spectra.length <= 0) { this.loadFromURL(url); } else { + let nmriumVersion = 3; + if (nmrium_info && nmrium_info["version"]) { + nmriumVersion = nmrium_info["version"] + } let mols = []; if (this.isString(nmrium_info.molecules)) { mols = JSON.parse(nmrium_info.molecules); @@ -496,6 +502,7 @@ export default { data: { spectra: spectra, molecules: mols, + version: nmriumVersion }, type: "nmrium", }; @@ -547,6 +554,7 @@ export default { { spectra: this.selectedSpectraData, molecules: this.currentMolecules, + version: this.version ? this.version : 3 } ) .catch((err) => { diff --git a/resources/js/Shared/SpectraViewer.vue b/resources/js/Shared/SpectraViewer.vue index bc255e6a..7a61930d 100644 --- a/resources/js/Shared/SpectraViewer.vue +++ b/resources/js/Shared/SpectraViewer.vue @@ -351,6 +351,10 @@ export default { nmrium_info = JSON.parse( response.data.nmrium_info ); + let nmriumVersion = 3; + if (nmrium_info && nmrium_info["version"]) { + nmriumVersion = nmrium_info["version"] + } if (nmrium_info && nmrium_info["spectra"]) { if (this.isString(nmrium_info["spectra"])) { spectra = JSON.parse( @@ -378,11 +382,11 @@ export default { "\n" + mol.molfile + "\n"; }); } - let data = { data: { spectra: spectra, molecules: mols, + version: nmriumVersion }, type: "nmrium", }; diff --git a/routes/web.php b/routes/web.php index cc7fecdf..854b55ec 100644 --- a/routes/web.php +++ b/routes/web.php @@ -220,8 +220,10 @@ Route::put('users/edit/{user}/password', [UsersController::class, 'updatePassword']) ->name('console.users.update-password'); - Route::put('users/edit/{user}/role', [UsersController::class, 'updateRole']) - ->name('console.users.update-role'); + Route::group(['middleware' => ['permission:manage roles']], function () { + Route::put('users/edit/{user}/role', [UsersController::class, 'updateRole']) + ->name('console.users.update-role'); + }); Route::delete('users/edit/{user}/photo', [UsersController::class, 'destroyPhoto']) ->name('console.users.destroy-photo'); diff --git a/tests/Feature/ApiTokenPermissionsTest.php b/tests/Feature/ApiTokenPermissionsTest.php index 679ef55b..b256fdb9 100644 --- a/tests/Feature/ApiTokenPermissionsTest.php +++ b/tests/Feature/ApiTokenPermissionsTest.php @@ -27,19 +27,18 @@ public function test_api_token_permissions_can_be_updated() $token = $user->tokens()->create([ 'name' => 'Test Token', 'token' => Str::random(40), - 'abilities' => ['create', 'read'], + 'abilities' => ['project:create', 'project:read'], ]); $response = $this->put('/user/api-tokens/'.$token->id, [ 'name' => $token->name, 'permissions' => [ - 'delete', - 'missing-permission', + 'project:delete', ], ]); - $this->assertTrue($user->fresh()->tokens->first()->can('delete')); - $this->assertFalse($user->fresh()->tokens->first()->can('read')); - $this->assertFalse($user->fresh()->tokens->first()->can('missing-permission')); + $this->assertTrue($user->fresh()->tokens->first()->can('project:delete')); + $this->assertFalse($user->fresh()->tokens->first()->can('project:read')); + $this->assertFalse($user->fresh()->tokens->first()->can('project:missing-permission')); } } diff --git a/tests/Feature/CreateApiTokenTest.php b/tests/Feature/CreateApiTokenTest.php index 1c4168b1..7d6bcdd5 100644 --- a/tests/Feature/CreateApiTokenTest.php +++ b/tests/Feature/CreateApiTokenTest.php @@ -26,14 +26,14 @@ public function test_api_tokens_can_be_created() $response = $this->post('/user/api-tokens', [ 'name' => 'Test Token', 'permissions' => [ - 'read', - 'update', + 'project:read', + 'project:update', ], ]); $this->assertCount(1, $user->fresh()->tokens); $this->assertEquals('Test Token', $user->fresh()->tokens->first()->name); - $this->assertTrue($user->fresh()->tokens->first()->can('read')); - $this->assertFalse($user->fresh()->tokens->first()->can('delete')); + $this->assertTrue($user->fresh()->tokens->first()->can('project:read')); + $this->assertFalse($user->fresh()->tokens->first()->can('project:delete')); } } diff --git a/tests/Feature/DeleteTeamTest.php b/tests/Feature/DeleteTeamTest.php index eb0ee812..8838ecbc 100644 --- a/tests/Feature/DeleteTeamTest.php +++ b/tests/Feature/DeleteTeamTest.php @@ -20,10 +20,12 @@ public function test_teams_can_be_deleted() ])); $team->users()->attach( - $otherUser = User::factory()->create(), ['role' => 'test-role'] + $otherUser = User::factory()->create(), ['role' => 'collaborator'] ); - $response = $this->delete('/teams/'.$team->id); + $response = $this->delete('/teams/'.$team->id, [ + 'password' => 'password', + ]); $this->assertNull($team->fresh()); $this->assertCount(0, $otherUser->fresh()->teams); diff --git a/tests/Feature/InviteTeamMemberTest.php b/tests/Feature/InviteTeamMemberTest.php index dcf5c0c7..6afa4092 100644 --- a/tests/Feature/InviteTeamMemberTest.php +++ b/tests/Feature/InviteTeamMemberTest.php @@ -20,7 +20,7 @@ public function test_team_members_can_be_invited_to_team() $response = $this->post('/teams/'.$user->currentTeam->id.'/members', [ 'email' => 'test@example.com', - 'role' => 'admin', + 'role' => 'owner', ]); Mail::assertSent(TeamInvitation::class); @@ -34,7 +34,7 @@ public function test_team_member_invitations_can_be_cancelled() $invitation = $user->currentTeam->teamInvitations()->create([ 'email' => 'test@example.com', - 'role' => 'admin', + 'role' => 'owner', ]); $response = $this->delete('/team-invitations/'.$invitation->id); diff --git a/tests/Feature/ProfileInformationTest.php b/tests/Feature/ProfileInformationTest.php index 33a42624..45dcd0f1 100644 --- a/tests/Feature/ProfileInformationTest.php +++ b/tests/Feature/ProfileInformationTest.php @@ -12,10 +12,15 @@ class ProfileInformationTest extends TestCase public function test_profile_information_can_be_updated() { - $this->actingAs($user = User::factory()->create()); + $user = User::factory()->create(); + + $this->actingAs($user); $response = $this->put('/user/profile-information', [ 'name' => 'Test Name', + 'first_name' => 'Test', + 'last_name' => 'Name', + 'username' => 'test', 'email' => 'test@example.com', ]); diff --git a/tests/Feature/RegistrationTest.php b/tests/Feature/RegistrationTest.php index aae144fc..1cd06bef 100644 --- a/tests/Feature/RegistrationTest.php +++ b/tests/Feature/RegistrationTest.php @@ -42,6 +42,9 @@ public function test_new_users_can_register() $response = $this->post('/register', [ 'name' => 'Test User', + 'first_name' => 'Test', + 'last_name' => 'User', + 'username' => 'test', 'email' => 'test@example.com', 'password' => 'password', 'password_confirmation' => 'password', diff --git a/tests/Feature/UpdateTeamMemberRoleTest.php b/tests/Feature/UpdateTeamMemberRoleTest.php index a9072f6d..da66e0dd 100644 --- a/tests/Feature/UpdateTeamMemberRoleTest.php +++ b/tests/Feature/UpdateTeamMemberRoleTest.php @@ -15,15 +15,15 @@ public function test_team_member_roles_can_be_updated() $this->actingAs($user = User::factory()->withPersonalTeam()->create()); $user->currentTeam->users()->attach( - $otherUser = User::factory()->create(), ['role' => 'admin'] + $otherUser = User::factory()->create(), ['role' => 'owner'] ); $response = $this->put('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id, [ - 'role' => 'editor', + 'role' => 'collaborator', ]); $this->assertTrue($otherUser->fresh()->hasTeamRole( - $user->currentTeam->fresh(), 'editor' + $user->currentTeam->fresh(), 'collaborator' )); } @@ -32,17 +32,17 @@ public function test_only_team_owner_can_update_team_member_roles() $user = User::factory()->withPersonalTeam()->create(); $user->currentTeam->users()->attach( - $otherUser = User::factory()->create(), ['role' => 'admin'] + $otherUser = User::factory()->create(), ['role' => 'owner'] ); $this->actingAs($otherUser); $response = $this->put('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id, [ - 'role' => 'editor', + 'role' => 'reviewer', ]); $this->assertTrue($otherUser->fresh()->hasTeamRole( - $user->currentTeam->fresh(), 'admin' + $user->currentTeam->fresh(), 'owner' )); } }