23 | */
24 | public function definition(): array
25 | {
26 | return [
27 | 'name' => fake()->name(),
28 | 'email' => fake()->unique()->safeEmail(),
29 | 'email_verified_at' => now(),
30 | 'password' => static::$password ??= Hash::make('password'),
31 | 'remember_token' => Str::random(10),
32 | ];
33 | }
34 |
35 | /**
36 | * Indicate that the model's email address should be unverified.
37 | */
38 | public function unverified(): static
39 | {
40 | return $this->state(fn (array $attributes) => [
41 | 'email_verified_at' => null,
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name');
17 | $table->string('email')->unique();
18 | $table->timestamp('email_verified_at')->nullable();
19 | $table->string('password');
20 | $table->rememberToken();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('users');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_100000_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->primary();
16 | $table->string('token');
17 | $table->timestamp('created_at')->nullable();
18 | });
19 | }
20 |
21 | /**
22 | * Reverse the migrations.
23 | */
24 | public function down(): void
25 | {
26 | Schema::dropIfExists('password_reset_tokens');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/database/migrations/2019_08_19_000000_create_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('uuid')->unique();
17 | $table->text('connection');
18 | $table->text('queue');
19 | $table->longText('payload');
20 | $table->longText('exception');
21 | $table->timestamp('failed_at')->useCurrent();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('failed_jobs');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->morphs('tokenable');
17 | $table->string('name');
18 | $table->string('token', 64)->unique();
19 | $table->text('abilities')->nullable();
20 | $table->timestamp('last_used_at')->nullable();
21 | $table->timestamp('expires_at')->nullable();
22 | $table->timestamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | */
29 | public function down(): void
30 | {
31 | Schema::dropIfExists('personal_access_tokens');
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/database/migrations/2021_11_18_142420_create_products_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('title');
17 | $table->boolean('active')->default(false);
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('products');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/database/migrations/tasks/2021_11_18_122318_create_posts_table.php:
--------------------------------------------------------------------------------
1 | id();
18 |
19 | //TODO Migrations Задание 2: Для title указать что значение по умолчанию NULL
20 |
21 | //TODO Migrations Задание 3: Для active указать что значение по умолчанию TRUE
22 |
23 | //TODO Migrations Задание 4: Добавить функционал soft delete
24 |
25 | //TODO Migrations Задание 5: Добавить поля с timestamps (created_at, updated_at) через 1 метод
26 | });
27 |
28 | Schema::table('posts', function (Blueprint $table) {
29 | //TODO Migrations Задание 6: Добавить поле description типа text (DEFAULT NULL) ПОСЛЕ поля title
30 |
31 | //TODO Migrations Задание 7: Сделать проверку на наличие поля active и в случаи успеха добавить поле main (boolean default false)
32 |
33 | //TODO Migrations Задание 8: Переименовать поле title в name
34 | });
35 |
36 | //TODO Migrations Задание 9: Переименовать таблицу posts в articles
37 |
38 | //TODO Migrations Задание 10: Добавить таблицу для связи articles и categories (belongsToMany) c foreign ключами
39 | }
40 |
41 | /**
42 | * Reverse the migrations.
43 | */
44 | public function down(): void
45 | {
46 | // TODO Migrations Задание 11: Удалить таблицы categories, articles, article_category если такие существуют
47 | }
48 | };
49 |
--------------------------------------------------------------------------------
/database/seeders/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 | create();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "type": "module",
4 | "scripts": {
5 | "dev": "vite",
6 | "build": "vite build"
7 | },
8 | "devDependencies": {
9 | "axios": "^1.6.4",
10 | "laravel-vite-plugin": "^1.0",
11 | "vite": "^5.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | tests/Feature
10 |
11 |
12 |
13 |
14 | app
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=301]
16 |
17 | # Send Requests To Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lee-to/laravel-check-your-skill-test/954f79a0e161ce27e9cc724adba30a54ce3d7778/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class);
50 |
51 | $response = $kernel->handle(
52 | $request = Request::capture()
53 | )->send();
54 |
55 | $kernel->terminate($request, $response);
56 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/public/web.config:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/resources/css/app.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lee-to/laravel-check-your-skill-test/954f79a0e161ce27e9cc724adba30a54ce3d7778/resources/css/app.css
--------------------------------------------------------------------------------
/resources/js/app.js:
--------------------------------------------------------------------------------
1 | require('./bootstrap');
2 |
--------------------------------------------------------------------------------
/resources/js/bootstrap.js:
--------------------------------------------------------------------------------
1 | window._ = require('lodash');
2 |
3 | /**
4 | * We'll load the axios HTTP library which allows us to easily issue requests
5 | * to our Laravel back-end. This library automatically handles sending the
6 | * CSRF token as a header based on the value of the "XSRF" token cookie.
7 | */
8 |
9 | window.axios = require('axios');
10 |
11 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
12 |
13 | /**
14 | * Echo exposes an expressive API for subscribing to channels and listening
15 | * for events that are broadcast by Laravel. Echo and event broadcasting
16 | * allows your team to easily build robust real-time web applications.
17 | */
18 |
19 | // import Echo from 'laravel-echo';
20 |
21 | // window.Pusher = require('pusher-js');
22 |
23 | // window.Echo = new Echo({
24 | // broadcaster: 'pusher',
25 | // key: process.env.MIX_PUSHER_APP_KEY,
26 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER,
27 | // forceTLS: true
28 | // });
29 |
--------------------------------------------------------------------------------
/resources/lang/en/auth.php:
--------------------------------------------------------------------------------
1 | 'These credentials do not match our records.',
17 | 'password' => 'The provided password is incorrect.',
18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
19 |
20 | ];
21 |
--------------------------------------------------------------------------------
/resources/lang/en/pagination.php:
--------------------------------------------------------------------------------
1 | '« Previous',
17 | 'next' => 'Next »',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/resources/lang/en/passwords.php:
--------------------------------------------------------------------------------
1 | 'Your password has been reset!',
17 | 'sent' => 'We have emailed your password reset link!',
18 | 'throttled' => 'Please wait before retrying.',
19 | 'token' => 'This password reset token is invalid.',
20 | 'user' => "We can't find a user with that email address.",
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/resources/lang/en/validation.php:
--------------------------------------------------------------------------------
1 | 'The :attribute must be accepted.',
17 | 'accepted_if' => 'The :attribute must be accepted when :other is :value.',
18 | 'active_url' => 'The :attribute is not a valid URL.',
19 | 'after' => 'The :attribute must be a date after :date.',
20 | 'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
21 | 'alpha' => 'The :attribute must only contain letters.',
22 | 'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
23 | 'alpha_num' => 'The :attribute must only contain letters and numbers.',
24 | 'array' => 'The :attribute must be an array.',
25 | 'before' => 'The :attribute must be a date before :date.',
26 | 'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
27 | 'between' => [
28 | 'numeric' => 'The :attribute must be between :min and :max.',
29 | 'file' => 'The :attribute must be between :min and :max kilobytes.',
30 | 'string' => 'The :attribute must be between :min and :max characters.',
31 | 'array' => 'The :attribute must have between :min and :max items.',
32 | ],
33 | 'boolean' => 'The :attribute field must be true or false.',
34 | 'confirmed' => 'The :attribute confirmation does not match.',
35 | 'current_password' => 'The password is incorrect.',
36 | 'date' => 'The :attribute is not a valid date.',
37 | 'date_equals' => 'The :attribute must be a date equal to :date.',
38 | 'date_format' => 'The :attribute does not match the format :format.',
39 | 'declined' => 'The :attribute must be declined.',
40 | 'declined_if' => 'The :attribute must be declined when :other is :value.',
41 | 'different' => 'The :attribute and :other must be different.',
42 | 'digits' => 'The :attribute must be :digits digits.',
43 | 'digits_between' => 'The :attribute must be between :min and :max digits.',
44 | 'dimensions' => 'The :attribute has invalid image dimensions.',
45 | 'distinct' => 'The :attribute field has a duplicate value.',
46 | 'email' => 'The :attribute must be a valid email address.',
47 | 'ends_with' => 'The :attribute must end with one of the following: :values.',
48 | 'exists' => 'The selected :attribute is invalid.',
49 | 'file' => 'The :attribute must be a file.',
50 | 'filled' => 'The :attribute field must have a value.',
51 | 'gt' => [
52 | 'numeric' => 'The :attribute must be greater than :value.',
53 | 'file' => 'The :attribute must be greater than :value kilobytes.',
54 | 'string' => 'The :attribute must be greater than :value characters.',
55 | 'array' => 'The :attribute must have more than :value items.',
56 | ],
57 | 'gte' => [
58 | 'numeric' => 'The :attribute must be greater than or equal to :value.',
59 | 'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
60 | 'string' => 'The :attribute must be greater than or equal to :value characters.',
61 | 'array' => 'The :attribute must have :value items or more.',
62 | ],
63 | 'image' => 'The :attribute must be an image.',
64 | 'in' => 'The selected :attribute is invalid.',
65 | 'in_array' => 'The :attribute field does not exist in :other.',
66 | 'integer' => 'The :attribute must be an integer.',
67 | 'ip' => 'The :attribute must be a valid IP address.',
68 | 'ipv4' => 'The :attribute must be a valid IPv4 address.',
69 | 'ipv6' => 'The :attribute must be a valid IPv6 address.',
70 | 'json' => 'The :attribute must be a valid JSON string.',
71 | 'lt' => [
72 | 'numeric' => 'The :attribute must be less than :value.',
73 | 'file' => 'The :attribute must be less than :value kilobytes.',
74 | 'string' => 'The :attribute must be less than :value characters.',
75 | 'array' => 'The :attribute must have less than :value items.',
76 | ],
77 | 'lte' => [
78 | 'numeric' => 'The :attribute must be less than or equal to :value.',
79 | 'file' => 'The :attribute must be less than or equal to :value kilobytes.',
80 | 'string' => 'The :attribute must be less than or equal to :value characters.',
81 | 'array' => 'The :attribute must not have more than :value items.',
82 | ],
83 | 'max' => [
84 | 'numeric' => 'The :attribute must not be greater than :max.',
85 | 'file' => 'The :attribute must not be greater than :max kilobytes.',
86 | 'string' => 'The :attribute must not be greater than :max characters.',
87 | 'array' => 'The :attribute must not have more than :max items.',
88 | ],
89 | 'mimes' => 'The :attribute must be a file of type: :values.',
90 | 'mimetypes' => 'The :attribute must be a file of type: :values.',
91 | 'min' => [
92 | 'numeric' => 'The :attribute must be at least :min.',
93 | 'file' => 'The :attribute must be at least :min kilobytes.',
94 | 'string' => 'The :attribute must be at least :min characters.',
95 | 'array' => 'The :attribute must have at least :min items.',
96 | ],
97 | 'multiple_of' => 'The :attribute must be a multiple of :value.',
98 | 'not_in' => 'The selected :attribute is invalid.',
99 | 'not_regex' => 'The :attribute format is invalid.',
100 | 'numeric' => 'The :attribute must be a number.',
101 | 'password' => 'The password is incorrect.',
102 | 'present' => 'The :attribute field must be present.',
103 | 'regex' => 'The :attribute format is invalid.',
104 | 'required' => 'The :attribute field is required.',
105 | 'required_if' => 'The :attribute field is required when :other is :value.',
106 | 'required_unless' => 'The :attribute field is required unless :other is in :values.',
107 | 'required_with' => 'The :attribute field is required when :values is present.',
108 | 'required_with_all' => 'The :attribute field is required when :values are present.',
109 | 'required_without' => 'The :attribute field is required when :values is not present.',
110 | 'required_without_all' => 'The :attribute field is required when none of :values are present.',
111 | 'prohibited' => 'The :attribute field is prohibited.',
112 | 'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
113 | 'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
114 | 'prohibits' => 'The :attribute field prohibits :other from being present.',
115 | 'same' => 'The :attribute and :other must match.',
116 | 'size' => [
117 | 'numeric' => 'The :attribute must be :size.',
118 | 'file' => 'The :attribute must be :size kilobytes.',
119 | 'string' => 'The :attribute must be :size characters.',
120 | 'array' => 'The :attribute must contain :size items.',
121 | ],
122 | 'starts_with' => 'The :attribute must start with one of the following: :values.',
123 | 'string' => 'The :attribute must be a string.',
124 | 'timezone' => 'The :attribute must be a valid timezone.',
125 | 'unique' => 'The :attribute has already been taken.',
126 | 'uploaded' => 'The :attribute failed to upload.',
127 | 'url' => 'The :attribute must be a valid URL.',
128 | 'uuid' => 'The :attribute must be a valid UUID.',
129 |
130 | /*
131 | |--------------------------------------------------------------------------
132 | | Custom Validation Language Lines
133 | |--------------------------------------------------------------------------
134 | |
135 | | Here you may specify custom validation messages for attributes using the
136 | | convention "attribute.rule" to name the lines. This makes it quick to
137 | | specify a specific custom language line for a given attribute rule.
138 | |
139 | */
140 |
141 | 'custom' => [
142 | 'attribute-name' => [
143 | 'rule-name' => 'custom-message',
144 | ],
145 | ],
146 |
147 | /*
148 | |--------------------------------------------------------------------------
149 | | Custom Validation Attributes
150 | |--------------------------------------------------------------------------
151 | |
152 | | The following language lines are used to swap our attribute placeholder
153 | | with something more reader friendly such as "E-Mail Address" instead
154 | | of "email". This simply helps us make our message more expressive.
155 | |
156 | */
157 |
158 | 'attributes' => [],
159 |
160 | ];
161 |
--------------------------------------------------------------------------------
/resources/views/auth.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/resources/views/eloquent/task2.blade.php:
--------------------------------------------------------------------------------
1 | @foreach($products as $product)
2 | {{ $loop->iteration }}.{{ $product->title }}
3 | @endforeach
4 |
--------------------------------------------------------------------------------
/resources/views/eloquent/task4.blade.php:
--------------------------------------------------------------------------------
1 | @isset($product->title)
2 | {{ $product->title }}
3 | @endisset
4 |
--------------------------------------------------------------------------------
/resources/views/hello.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Hello
8 |
9 |
10 | Hello
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/layouts/app.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Layout
8 |
9 |
10 |
11 |
12 |
13 | @yield('content')
14 |
15 |
16 |
--------------------------------------------------------------------------------
/resources/views/login.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Empty page
8 |
9 |
10 | Empty page
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/pages/contact.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Empty page
8 |
9 |
10 | Empty page
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/shared/empty.blade.php:
--------------------------------------------------------------------------------
1 | Ничего не найдено
--------------------------------------------------------------------------------
/resources/views/shared/menu.blade.php:
--------------------------------------------------------------------------------
1 |
2 | - Menu Item 1
3 | - Menu Item 2
4 | - Menu Item 3
5 |
--------------------------------------------------------------------------------
/resources/views/shared/user.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $user->name }}
3 |
--------------------------------------------------------------------------------
/resources/views/table.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/resources/views/users/form.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Empty page
8 |
9 |
10 | Empty page
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/users/index.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Empty page
8 |
9 |
10 | Empty page
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/users/show.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ $user->name }}
8 |
9 |
10 | {{ $user->name }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/resources/views/welcome.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Laravel
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/routes/api.php:
--------------------------------------------------------------------------------
1 | get('/user', function (Request $request) {
7 | return $request->user();
8 | });
9 |
10 | Route::group(['middleware' => 'auth:sanctum'], function() {
11 | // TODO Route Задача 13: Добавить apiResource контроллер - Api/V1/UserController.
12 | // Префикс урла должен быть /api/v1
13 | // Полный урл /api/v1/users (не забывайте что это api routes)
14 | // Одна строка кода
15 | });
16 |
--------------------------------------------------------------------------------
/routes/console.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
8 | })->purpose('Display an inspiring quote')->hourly();
9 |
--------------------------------------------------------------------------------
/routes/default.php:
--------------------------------------------------------------------------------
1 | name('login');
6 |
7 | Route::get('/table', [\App\Http\Controllers\IndexController::class, 'table'])->name('table');
8 |
9 | Route::get('/auth', [\App\Http\Controllers\IndexController::class, 'auth'])->name('default.auth');
10 |
11 | Route::get('/eloquent/task2', [\App\Http\Controllers\EloquentController::class, 'task2'])->name('eloquent.task2');
12 | Route::get('/eloquent/task3', [\App\Http\Controllers\EloquentController::class, 'task3'])->name('eloquent.task3');
13 | Route::get('/eloquent/task4/{id}', [\App\Http\Controllers\EloquentController::class, 'task4'])->name('eloquent.task4');
14 |
15 | Route::post('/eloquent/task5', [\App\Http\Controllers\EloquentController::class, 'task5'])->name('eloquent.task5');
16 | Route::post('/eloquent/task6/{id}', [\App\Http\Controllers\EloquentController::class, 'task6'])->name('eloquent.task6');
17 | Route::delete('/eloquent/task7', [\App\Http\Controllers\EloquentController::class, 'task7'])->name('eloquent.task7');
18 |
19 |
20 | Route::resource('items', \App\Http\Controllers\ItemController::class);
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 | Admin/IndexController -> index
40 |
41 |
42 | //TODO Route Задание 10: Добавить роут POST /admin/post -> Admin/IndexController -> post
43 |
44 |
45 | //TODO Route Задание 11: Организовать группу роутов (Route::group()) объединенных префиксом - security и мидлваром auth
46 |
47 | // Задачи внутри группы роутов security
48 | //TODO Задание 12: Добавить роут GET /admin/auth -> Admin/IndexController -> auth
49 |
50 | require __DIR__ . '/default.php';
51 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !public/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/app/public/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/debugbar/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/.gitignore:
--------------------------------------------------------------------------------
1 | compiled.php
2 | config.php
3 | down
4 | events.scanned.php
5 | maintenance.php
6 | routes.php
7 | routes.scanned.php
8 | schedule-*
9 | services.json
10 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !data/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/framework/cache/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/testing/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/tests/CreatesApplication.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
18 |
19 | return $app;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Feature/AuthTest.php:
--------------------------------------------------------------------------------
1 | create(['id' => 1]);
17 |
18 | $this->assertFalse($user->can('create', Item::class));
19 |
20 | $user = User::factory()->create(['id' => 10]);
21 |
22 | $this->assertTrue($user->can('create', Item::class));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Feature/BladeTest.php:
--------------------------------------------------------------------------------
1 | get('/');
17 |
18 | $response->assertOk();
19 | $response->assertViewIs('welcome');
20 | $response->assertViewHas('users');
21 | }
22 |
23 | public function test_task_2(): void
24 | {
25 | $response = $this->get('/table');
26 |
27 | $response->assertOk();
28 | $response->assertSee('Layout');
29 | }
30 |
31 | public function test_task_3(): void
32 | {
33 | $response = $this->get('/table');
34 |
35 | $response->assertOk();
36 | $response->assertSee('Menu Item 1');
37 | }
38 |
39 | public function test_task_4(): void
40 | {
41 | $user = User::factory()->create();
42 |
43 | $response = $this->get('/auth');
44 | $response->assertOk();
45 | $response->assertDontSee($user->id);
46 |
47 | $response = $this->actingAs($user)->get('/auth');
48 | $response->assertOk();
49 | $response->assertSee($user->id);
50 | }
51 |
52 | public function test_task_5(): void
53 | {
54 | $aliases = Blade::getClassComponentAliases();
55 |
56 | $this->assertTrue(isset($aliases['hello']));
57 |
58 | $response = $this->get('/');
59 | $response->assertOk();
60 |
61 | $response->assertSee(now()->format('Y-m-d'));
62 | }
63 |
64 | public function test_task_6_7(): void
65 | {
66 | $response = $this->get('/table');
67 | $response->assertDontSee(`class="bg-red-500"`);
68 | $this->assertStringContainsString('Ничего не найдено', $response->content());
69 |
70 | User::factory()->count(10)->create();
71 |
72 | $response = $this->get('/table');
73 | $response->assertSee(`class="bg-red-500"`);
74 |
75 | $this->assertStringNotContainsString('Ничего не найдено', $response->content());
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/Feature/MigrationsTest.php:
--------------------------------------------------------------------------------
1 | expectNotToPerformAssertions();
16 |
17 | Artisan::call('migrate', ['--path' => 'database/migrations/tasks']);
18 | }
19 |
20 | public function test_tables_exists(): void
21 | {
22 | $this->assertTrue(Schema::hasTable('categories'));
23 | $this->assertTrue(Schema::hasTable('articles'));
24 | $this->assertTrue(Schema::hasTable('article_category'));
25 | }
26 |
27 | public function test_columns_exists(): void
28 | {
29 | $this->assertTrue(Schema::hasColumn('categories', 'title'));
30 |
31 | $this->assertTrue(Schema::hasColumns('articles', ['name', 'description', 'active', 'main']));
32 | }
33 |
34 | public function test_soft_delete(): void
35 | {
36 | $this->assertTrue(Schema::hasColumns('articles', ['deleted_at']));
37 | }
38 |
39 | public function test_timestamps(): void
40 | {
41 | $this->assertTrue(Schema::hasColumns('articles', ['created_at', 'updated_at']));
42 | }
43 |
44 | public function test_default_nullable(): void
45 | {
46 | $article = Article::factory()->create(['name' => null]);
47 |
48 | $this->assertNull($article->name);
49 | }
50 |
51 | public function test_relation_table(): void
52 | {
53 | $categories = Category::factory()->count(3);
54 |
55 | $article = Article::factory()->has($categories)->create();
56 |
57 | $this->assertEquals($article->categories->count(), 3);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/Feature/ModelTest.php:
--------------------------------------------------------------------------------
1 | 'Test'];
16 |
17 | Item::create($item);
18 |
19 | $this->assertDatabaseHas('products', $item);
20 | }
21 |
22 | public function test_task_2(): void
23 | {
24 | $item1 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinutes(5)]);
25 | $item2 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinutes(4)]);
26 | $item3 = Item::factory()->create(['active' => false, 'created_at' => now()->subMinutes(3)]);
27 | $item4 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinutes(2)]);
28 | $item5 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinute()]);
29 |
30 | $response = $this->get('/eloquent/task2');
31 |
32 | $response->assertDontSee($item1->title);
33 | $response->assertDontSee($item3->title);
34 |
35 | $response->assertSee('1.' . $item5->title);
36 | $response->assertSee('2.' . $item4->title);
37 | $response->assertSee('3.' . $item2->title);
38 | }
39 |
40 | public function test_task_3(): void
41 | {
42 | $item1 = Item::factory()->create(['active' => true]);
43 | $item2 = Item::factory()->create(['active' => false]);
44 |
45 | $response = $this->get('/eloquent/task3');
46 |
47 | $response->assertSee($item1->title);
48 | $response->assertDontSee($item2->title);
49 | }
50 |
51 | public function test_task_4(): void
52 | {
53 | $response = $this->get('/eloquent/task4/1');
54 | $response->assertStatus(404);
55 |
56 | $item = Item::factory()->create();
57 | $response = $this->get('/eloquent/task4/' . $item->id);
58 | $response->assertStatus(200);
59 | $response->assertViewHas('product', $item);
60 | }
61 |
62 | public function test_task_5(): void
63 | {
64 | $response = $this->post('/eloquent/task5', ['title' => 'Test']);
65 | $response->assertRedirect();
66 | $this->assertDatabaseHas('products', ['title' => 'Test']);
67 | }
68 |
69 | public function test_task_6(): void
70 | {
71 | $item = new Item();
72 | $item->title = 'Old title';
73 | $item->save();
74 |
75 | $this->assertDatabaseHas('products', ['title' => 'Old title']);
76 |
77 | $response = $this->post('/eloquent/task6/' . $item->id, ['title' => 'New title']);
78 | $response->assertRedirect();
79 |
80 | $this->assertDatabaseMissing('products', ['title' => 'Old title']);
81 | $this->assertDatabaseHas('products', ['title' => 'New title']);
82 | }
83 |
84 | public function test_task_7(): void
85 | {
86 | $products = Item::factory(4)->create();
87 | $this->assertDatabaseCount('products', 4);
88 |
89 | $response = $this->delete('/eloquent/task7', [
90 | 'products' => $products->pluck('id', 'id')
91 | ]);
92 |
93 | $response->assertRedirect();
94 | $this->assertDatabaseCount('products', 0);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/tests/Feature/RouteTest.php:
--------------------------------------------------------------------------------
1 | get('/hello');
17 | $response->assertViewIs('hello');
18 | }
19 |
20 | public function test_task_2(): void
21 | {
22 | $response = $this->get('/');
23 | $response->assertViewIs('welcome');
24 | $response->assertViewHas('title', 'Welcome');
25 | }
26 |
27 | public function test_task_3(): void
28 | {
29 | $response = $this->get(route('contact'));
30 | $response->assertViewIs('pages.contact');
31 | }
32 |
33 | public function test_task_4(): void
34 | {
35 | $user = User::factory()->create();
36 |
37 | $response = $this->get("/users/{$user->id}");
38 |
39 | $response->assertOk();
40 | $response->assertViewIs('users.show');
41 | }
42 |
43 | public function test_task_5(): void
44 | {
45 | $user = User::factory()->create();
46 |
47 | $response = $this->get("/users/bind/{$user->id}");
48 |
49 | $response->assertOk();
50 | $response->assertViewIs('users.show');
51 | }
52 |
53 | public function test_tasks_4_5_notfound(): void
54 | {
55 | $response = $this->get('/user/test');
56 | $response->assertNotFound();
57 | }
58 |
59 | public function test_task_6(): void
60 | {
61 | $response = $this->get('/bad');
62 |
63 | $response->assertRedirect('/good');
64 | }
65 |
66 | public function test_task_7(): void
67 | {
68 | $user = User::factory()->create();
69 |
70 | $response = $this->get('/users_crud');
71 |
72 | $response->assertViewIs('users.index');
73 | $response->assertViewHas('users');
74 |
75 | $response = $this->get("/users_crud/{$user->id}");
76 |
77 | $response->assertViewIs('users.show');
78 | $response->assertViewHas('user');
79 |
80 | $response = $this->get('/users_crud/create');
81 |
82 | $response->assertViewIs('users.form');
83 |
84 | $response = $this->get("/users_crud/{$user->id}/edit");
85 |
86 | $response->assertViewIs('users.form');
87 |
88 | $response = $this->post('/users_crud', $this->getUserRequestData());
89 |
90 | $response->assertRedirect('/users_crud');
91 |
92 | $response = $this->put("/users_crud/{$user->id}", $this->getUserRequestData());
93 |
94 | $response->assertRedirect('/users_crud');
95 |
96 | $response = $this->delete("/users_crud/{$user->id}");
97 |
98 | $response->assertRedirect('/users_crud');
99 | }
100 |
101 | public function test_tasks_8_12(): void
102 | {
103 | $response = $this->get('/dashboard/admin');
104 | $response->assertViewIs('welcome');
105 |
106 | $response = $this->post('/dashboard/admin/post');
107 | $response->assertViewIs('welcome');
108 | $response->assertStatus(200);
109 |
110 | $response = $this->get('/security/admin/auth');
111 | $response->assertRedirect('login');
112 |
113 | $user = User::factory()->create();
114 |
115 | $response = $this->actingAs($user)->get('/security/admin/auth');
116 | $response->assertStatus(200);
117 | }
118 |
119 | public function test_task_13(): void
120 | {
121 | $userAuth = User::factory()->create();
122 |
123 | $response = $this->actingAs($userAuth)->get('/api/v1/users');
124 | $response->assertOk();
125 |
126 | $data = $this->getUserRequestData();
127 | $response = $this->actingAs($userAuth)->post('/api/v1/users', $data);
128 | $response->assertCreated();
129 | $this->assertDatabaseHas(User::class, $data);
130 |
131 | $user = User::factory()->create();
132 | $data = $this->getUserRequestData();
133 | $response = $this->actingAs($userAuth)->put('/api/v1/users/' . $user->id, $data);
134 | $response->assertOk();
135 | $this->assertDatabaseHas(User::class, $data);
136 |
137 | $data = $this->getUserRequestData();
138 | $response = $this->actingAs($userAuth)->delete('/api/v1/users/' . $user->id);
139 | $response->assertNoContent();
140 | $this->assertDatabaseMissing(User::class, $data);
141 | }
142 |
143 | private function getUserRequestData()
144 | {
145 | return [
146 | 'name' => 'Name ' . random_int(1, 1000),
147 | 'email' => uniqid() . '@example.com',
148 | 'password' => Hash::make('123'),
149 | ];
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/tests/Feature/ValidationTest.php:
--------------------------------------------------------------------------------
1 | post('/items', ['title' => 'Testing']);
16 |
17 | $response->assertSessionDoesntHaveErrors();
18 |
19 | $response = $this->post('/items', []);
20 |
21 | $response->assertSessionHasErrors('title');
22 |
23 | $response = $this->post('/items', ['title' => 'T']);
24 |
25 | $response->assertSessionHasErrors('title');
26 |
27 | $response = $this->post('/items', ['title' => 'Testing Testing Testing Testing Testing']);
28 |
29 | $response->assertSessionHasErrors('title');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 |