Compare commits

...

3 Commits

Author SHA1 Message Date
AslanAV 306d73ff23 add user admin with DatabaseSeeder.php 2024-01-12 09:11:27 +03:00
AslanAV 1e3228e8b3 refactor CI deploy run 2024-01-12 09:10:59 +03:00
AslanAV d5062e8ebe add tests and lint? and fix lints errors 2024-01-11 17:05:53 +03:00
26 changed files with 298 additions and 55 deletions

49
.gitea/workflows/php.yml Normal file
View File

@ -0,0 +1,49 @@
name: Tests & Lint & Deploy to Railway
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: [ '8.1' ]
steps:
- uses: actions/checkout@v3
- name: Set up PHP ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
- name: PHP Security Checker
uses: StephaneBour/actions-php-security-checker@1.1
- name: Setup project
run: make setup
- name: Check lint
run: make lint
- name: Execute tests (Unit and Feature tests) via PHPUnit
run: make test-coverage
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Deploy
run: make deploy
env:
SSH_TOKEN: ${{ secrets.SSH_TOKEN }}

View File

@ -25,10 +25,12 @@ class ConfirmablePasswordController extends Controller
*/ */
public function store(Request $request): RedirectResponse public function store(Request $request): RedirectResponse
{ {
if (! Auth::guard('web')->validate([ if (
! Auth::guard('web')->validate([
'email' => $request->user()->email, 'email' => $request->user()->email,
'password' => $request->password, 'password' => $request->password,
])) { ])
) {
throw ValidationException::withMessages([ throw ValidationException::withMessages([
'password' => __('auth.password'), 'password' => __('auth.password'),
]); ]);

View File

@ -8,5 +8,6 @@ use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController class Controller extends BaseController
{ {
use AuthorizesRequests, ValidatesRequests; use AuthorizesRequests;
use ValidatesRequests;
} }

View File

@ -17,7 +17,8 @@ class ProfileUpdateRequest extends FormRequest
{ {
return [ return [
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)], 'email' => ['required', 'string', 'lowercase', 'email', 'max:255',
Rule::unique(User::class)->ignore($this->user()->id)],
]; ];
} }
} }

View File

@ -10,7 +10,9 @@ use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable class User extends Authenticatable
{ {
use HasApiTokens, HasFactory, Notifiable; use HasApiTokens;
use HasFactory;
use Notifiable;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.

View File

@ -20,7 +20,9 @@
"nunomaduro/collision": "^7.10.0", "nunomaduro/collision": "^7.10.0",
"phpunit/phpunit": "^10.5.5", "phpunit/phpunit": "^10.5.5",
"spatie/laravel-ignition": "^2.4.0", "spatie/laravel-ignition": "^2.4.0",
"barryvdh/laravel-ide-helper": "^2.13.0" "barryvdh/laravel-ide-helper": "^2.13.0",
"squizlabs/php_codesniffer": "^3.8.0",
"phpstan/phpstan": "^1.10.55"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -35,6 +37,8 @@
} }
}, },
"scripts": { "scripts": {
"phpcs": "phpcs",
"phpcbf": "phpcbf",
"post-autoload-dump": [ "post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi" "@php artisan package:discover --ansi"

156
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7ab883d941740dee8af1ec0280a43509", "content-hash": "ee98f0386c39f019aa32fcd8e854a68e",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@ -7126,16 +7126,16 @@
}, },
{ {
"name": "phpdocumentor/type-resolver", "name": "phpdocumentor/type-resolver",
"version": "1.7.3", "version": "1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git", "url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" "reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fad452781b3d774e3337b0c0b245dd8e5a4455fc",
"reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7178,9 +7178,9 @@
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": { "support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues", "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.0"
}, },
"time": "2023-08-12T11:01:26+00:00" "time": "2024-01-11T11:49:22+00:00"
}, },
{ {
"name": "phpstan/phpdoc-parser", "name": "phpstan/phpdoc-parser",
@ -7229,6 +7229,68 @@
}, },
"time": "2024-01-04T17:06:16+00:00" "time": "2024-01-04T17:06:16+00:00"
}, },
{
"name": "phpstan/phpstan",
"version": "1.10.55",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a88f9d18ddf4cf54c922fbeac16c4cb164c5949",
"reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949",
"shasum": ""
},
"require": {
"php": "^7.2|^8.0"
},
"conflict": {
"phpstan/phpstan-shim": "*"
},
"bin": [
"phpstan",
"phpstan.phar"
],
"type": "library",
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPStan - PHP Static Analysis Tool",
"keywords": [
"dev",
"static analysis"
],
"support": {
"docs": "https://phpstan.org/user-guide/getting-started",
"forum": "https://github.com/phpstan/phpstan/discussions",
"issues": "https://github.com/phpstan/phpstan/issues",
"security": "https://github.com/phpstan/phpstan/security/policy",
"source": "https://github.com/phpstan/phpstan-src"
},
"funding": [
{
"url": "https://github.com/ondrejmirtes",
"type": "github"
},
{
"url": "https://github.com/phpstan",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
"type": "tidelift"
}
],
"time": "2024-01-08T12:32:40+00:00"
},
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "10.1.11", "version": "10.1.11",
@ -8922,6 +8984,86 @@
], ],
"time": "2024-01-04T14:51:24+00:00" "time": "2024-01-04T14:51:24+00:00"
}, },
{
"name": "squizlabs/php_codesniffer",
"version": "3.8.0",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
"reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5805f7a4e4958dbb5e944ef1e6edae0a303765e7",
"reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"bin": [
"bin/phpcs",
"bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "Former lead"
},
{
"name": "Juliette Reinders Folmer",
"role": "Current lead"
},
{
"name": "Contributors",
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards",
"static analysis"
],
"support": {
"issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
"security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
"source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
},
"funding": [
{
"url": "https://github.com/PHPCSStandards",
"type": "github"
},
{
"url": "https://github.com/jrfnl",
"type": "github"
},
{
"url": "https://opencollective.com/php_codesniffer",
"type": "open_collective"
}
],
"time": "2023-12-08T12:32:31+00:00"
},
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v6.4.0", "version": "v6.4.0",

View File

@ -13,11 +13,12 @@ class DatabaseSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
// \App\Models\User::factory(10)->create(); \App\Models\User::factory(10)->create();
// \App\Models\User::factory()->create([ \App\Models\User::factory()->create([
// 'name' => 'Test User', 'name' => 'admin',
// 'email' => 'test@example.com', 'email' => 'test@example.com',
// ]); 'password' => 123456
]);
} }
} }

41
phpcs.xml Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0"?>
<ruleset name="PlatformApi">
<description>PSR12 Laravel standards.</description>
<rule ref="PSR12"/>
<arg name="basepath" value="."/>
<arg name="colors"/>
<arg name="parallel" value="75"/>
<arg value="np"/>
<arg name="extensions" value="php"/>
<file>app</file>
<file>config</file>
<file>resources</file>
<file>routes</file>
<file>tests</file>
<file>database</file>
<rule ref="Generic.ControlStructures.InlineControlStructure">
<properties>
<property name="error" value="true"/>
</properties>
</rule>
<exclude-pattern>app/Console/Kernel.php</exclude-pattern>
<exclude-pattern>app/Http/Controllers/Controller.php</exclude-pattern>
<exclude-pattern>app/Http/Controllers/Auth/*</exclude-pattern>
<exclude-pattern>app/Http/Requests/Auth/LoginRequest.php</exclude-pattern>
<exclude-pattern>bootstrap/cache/*</exclude-pattern>
<exclude-pattern>config/*</exclude-pattern>
<exclude-pattern>public/index.php</exclude-pattern>
<exclude-pattern>storage/framework/views/*</exclude-pattern>
<exclude-pattern>server.php</exclude-pattern>
<exclude-pattern>*/migrations/*</exclude-pattern>
<exclude-pattern>*/seeds/*</exclude-pattern>
<exclude-pattern>*/*.blade.php</exclude-pattern>
<exclude-pattern>*/*.js</exclude-pattern>
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>node_modules/*</exclude-pattern>
</ruleset>

View File

@ -21,8 +21,8 @@
<env name="APP_ENV" value="testing"/> <env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/> <env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/> <env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> --> <env name="DB_CONNECTION" value="sqlite"/>
<!-- <env name="DB_DATABASE" value=":memory:"/> --> <env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/> <env name="MAIL_MAILER" value="array"/>
<env name="PULSE_ENABLED" value="false"/> <env name="PULSE_ENABLED" value="false"/>
<env name="QUEUE_CONNECTION" value="sync"/> <env name="QUEUE_CONNECTION" value="sync"/>

View File

@ -11,14 +11,14 @@ class AuthenticationTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_login_screen_can_be_rendered(): void public function testLoginScreenCanBeRendered(): void
{ {
$response = $this->get('/login'); $response = $this->get('/login');
$response->assertStatus(200); $response->assertStatus(200);
} }
public function test_users_can_authenticate_using_the_login_screen(): void public function testUsersCanAuthenticateUsingTheLoginScreen(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -31,7 +31,7 @@ class AuthenticationTest extends TestCase
$response->assertRedirect(RouteServiceProvider::HOME); $response->assertRedirect(RouteServiceProvider::HOME);
} }
public function test_users_can_not_authenticate_with_invalid_password(): void public function testUsersCanNotAuthenticateWithInvalidPassword(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -43,7 +43,7 @@ class AuthenticationTest extends TestCase
$this->assertGuest(); $this->assertGuest();
} }
public function test_users_can_logout(): void public function testUsersCanLogout(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();

View File

@ -14,7 +14,7 @@ class EmailVerificationTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_email_verification_screen_can_be_rendered(): void public function testEmailVerificationScreenCanBeRendered(): void
{ {
$user = User::factory()->create([ $user = User::factory()->create([
'email_verified_at' => null, 'email_verified_at' => null,
@ -25,7 +25,7 @@ class EmailVerificationTest extends TestCase
$response->assertStatus(200); $response->assertStatus(200);
} }
public function test_email_can_be_verified(): void public function testEmailCanBeVerified(): void
{ {
$user = User::factory()->create([ $user = User::factory()->create([
'email_verified_at' => null, 'email_verified_at' => null,
@ -46,7 +46,7 @@ class EmailVerificationTest extends TestCase
$response->assertRedirect(RouteServiceProvider::HOME . '?verified=1'); $response->assertRedirect(RouteServiceProvider::HOME . '?verified=1');
} }
public function test_email_is_not_verified_with_invalid_hash(): void public function testEmailIsNotVerifiedWithInvalidHash(): void
{ {
$user = User::factory()->create([ $user = User::factory()->create([
'email_verified_at' => null, 'email_verified_at' => null,

View File

@ -10,7 +10,7 @@ class PasswordConfirmationTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_confirm_password_screen_can_be_rendered(): void public function testConfirmPasswordScreenCanBeRendered(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -19,7 +19,7 @@ class PasswordConfirmationTest extends TestCase
$response->assertStatus(200); $response->assertStatus(200);
} }
public function test_password_can_be_confirmed(): void public function testPasswordCanBeConfirmed(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -31,7 +31,7 @@ class PasswordConfirmationTest extends TestCase
$response->assertSessionHasNoErrors(); $response->assertSessionHasNoErrors();
} }
public function test_password_is_not_confirmed_with_invalid_password(): void public function testPasswordIsNotConfirmedWithInvalidPassword(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();

View File

@ -12,14 +12,14 @@ class PasswordResetTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_reset_password_link_screen_can_be_rendered(): void public function testResetPasswordLinkScreenCanBeRendered(): void
{ {
$response = $this->get('/forgot-password'); $response = $this->get('/forgot-password');
$response->assertStatus(200); $response->assertStatus(200);
} }
public function test_reset_password_link_can_be_requested(): void public function testResetPasswordLinkCanBeRequested(): void
{ {
Notification::fake(); Notification::fake();
@ -30,7 +30,7 @@ class PasswordResetTest extends TestCase
Notification::assertSentTo($user, ResetPassword::class); Notification::assertSentTo($user, ResetPassword::class);
} }
public function test_reset_password_screen_can_be_rendered(): void public function testResetPasswordScreenCanBeRendered(): void
{ {
Notification::fake(); Notification::fake();
@ -47,7 +47,7 @@ class PasswordResetTest extends TestCase
}); });
} }
public function test_password_can_be_reset_with_valid_token(): void public function testPasswordCanbeResetWithValidToken(): void
{ {
Notification::fake(); Notification::fake();

View File

@ -11,7 +11,7 @@ class PasswordUpdateTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_password_can_be_updated(): void public function testPasswordCanBeUpdated(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -31,7 +31,7 @@ class PasswordUpdateTest extends TestCase
$this->assertTrue(Hash::check('new-password', $user->refresh()->password)); $this->assertTrue(Hash::check('new-password', $user->refresh()->password));
} }
public function test_correct_password_must_be_provided_to_update_password(): void public function testCorrectPasswordMustBeProvidedToUpdatePassword(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();

View File

@ -10,14 +10,14 @@ class RegistrationTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_registration_screen_can_be_rendered(): void public function testRegistrationScreenCanBeRendered(): void
{ {
$response = $this->get('/register'); $response = $this->get('/register');
$response->assertStatus(200); $response->assertStatus(200);
} }
public function test_new_users_can_register(): void public function testNewUsersCanRegister(): void
{ {
$response = $this->post('/register', [ $response = $this->post('/register', [
'name' => 'Test User', 'name' => 'Test User',

View File

@ -10,7 +10,7 @@ class ExampleTest extends TestCase
/** /**
* A basic test example. * A basic test example.
*/ */
public function test_the_application_returns_a_successful_response(): void public function testTheApplicationReturnsASuccessfulResponse(): void
{ {
$response = $this->get('/'); $response = $this->get('/');

View File

@ -10,7 +10,7 @@ class ProfileTest extends TestCase
{ {
use RefreshDatabase; use RefreshDatabase;
public function test_profile_page_is_displayed(): void public function testProfilePageIsDisplayed(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -21,7 +21,7 @@ class ProfileTest extends TestCase
$response->assertOk(); $response->assertOk();
} }
public function test_profile_information_can_be_updated(): void public function testProfileInformationCanBeUpdated(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -43,7 +43,7 @@ class ProfileTest extends TestCase
$this->assertNull($user->email_verified_at); $this->assertNull($user->email_verified_at);
} }
public function test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged(): void public function testEmailVerificationStatusIsUnchangedWhenTheEmailAddressAsUnchanged(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -61,7 +61,7 @@ class ProfileTest extends TestCase
$this->assertNotNull($user->refresh()->email_verified_at); $this->assertNotNull($user->refresh()->email_verified_at);
} }
public function test_user_can_delete_their_account(): void public function testUserCanDeleteTheirAccount(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();
@ -79,7 +79,7 @@ class ProfileTest extends TestCase
$this->assertNull($user->fresh()); $this->assertNull($user->fresh());
} }
public function test_correct_password_must_be_provided_to_delete_account(): void public function testCorrectPasswordMustBeProvidedToDeleteAccount(): void
{ {
$user = User::factory()->create(); $user = User::factory()->create();

View File

@ -9,7 +9,7 @@ class ExampleTest extends TestCase
/** /**
* A basic test example. * A basic test example.
*/ */
public function test_that_true_is_true(): void public function testThatTrueIsTrue(): void
{ {
$this->assertTrue(true); $this->assertTrue(true);
} }