Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/Commands/InitCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -428,22 +428,26 @@ protected function runMigrations(): void

protected function createAdminUser(string $kebabName, string $serviceKey = '', string $serviceName = ''): array
{
$adminEmail = when(empty($serviceKey), "admin@{$kebabName}.com", "admin.{$serviceKey}@{$kebabName}.com");
$isServiceAdmin = (!empty($serviceKey) && !empty($serviceName));

$adminEmail = when($isServiceAdmin, "admin.{$serviceKey}@{$kebabName}.com", "admin@{$kebabName}.com");
$defaultPassword = substr(md5(uniqid()), 0, 8);

$serviceLabel = when(!empty($serviceName), " for {$serviceName}");
$serviceLabel = when($isServiceAdmin, " for {$serviceName}");
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The when() helper on this line is missing the third parameter (default value). When $isServiceAdmin is false, this will return null instead of an empty string. This could result in the service label being null rather than empty, which may cause type inconsistencies or unexpected output.

Consider changing to:

$serviceLabel = when($isServiceAdmin, " for {$serviceName}", '');
Suggested change
$serviceLabel = when($isServiceAdmin, " for {$serviceName}");
$serviceLabel = when($isServiceAdmin, " for {$serviceName}", '');

Copilot uses AI. Check for mistakes.

$adminCredentials = [
'email' => $this->ask("Please enter admin email{$serviceLabel}", $adminEmail),
'password' => $this->ask("Please enter admin password{$serviceLabel}", $defaultPassword),
];

$adminName = when($isServiceAdmin, "{$serviceName} Admin", 'Admin');

if ($this->authType === AuthTypeEnum::None) {
$adminCredentials['name'] = $this->ask("Please enter admin name{$serviceLabel}", "{$serviceName} Admin");
$adminCredentials['name'] = $this->ask("Please enter admin name{$serviceLabel}", $adminName);
$adminCredentials['role_id'] = $this->ask("Please enter admin role id{$serviceLabel}", RoleEnum::Admin->value);
}

if (empty($serviceName)) {
if (!$isServiceAdmin) {
$this->adminCredentials = $adminCredentials;
}

Expand Down
141 changes: 141 additions & 0 deletions tests/InitCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace RonasIT\ProjectInitializator\Tests;

use RonasIT\ProjectInitializator\Commands\InitCommand;
use RonasIT\ProjectInitializator\Tests\Support\Traits\InitCommandMockTrait;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class InitCommandTest extends TestCase
{
Expand Down Expand Up @@ -926,4 +929,142 @@ public function testRunWithClerkAdditionalAdminsWithoutDefaultAdmin(): void
->expectsConfirmation('Do you want to uninstall project-initializator package?')
->assertExitCode(0);
}

public function testDefaultAdminsCredentialsNoneAuth()
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test method is missing the : void return type declaration. For consistency with other recently added test methods in this file (like testRunWithClerkMobileAppWithPintInstalled and testRunWithClerkAdditionalAdminsWithoutDefaultAdmin), this method should include the return type.

Add : void after the method signature:

public function testDefaultAdminsCredentialsNoneAuth(): void
Suggested change
public function testDefaultAdminsCredentialsNoneAuth()
public function testDefaultAdminsCredentialsNoneAuth(): void

Copilot uses AI. Check for mistakes.
{
$this->mockNativeFunction(
'\Winter\LaravelConfigWriter',
$this->changeEnvFileCall('.env.example', 'env.example.yml', 'env.example_app_name_not_pascal_case.yml'),
$this->changeEnvFileCall('.env.development', 'env.development.yml', 'env.development_app_name_not_pascal_case.yml'),
$this->changeConfigFileCall('config/auto-doc.php', 'auto_doc.php', 'auto_doc_after_changes.php'),
$this->changeConfigFileCall('config/telescope.php', 'telescope_config.php', 'telescope_config_after_initialization.php'),
);

$this->mockNativeFunction(
'RonasIT\ProjectInitializator\Commands',
$this->callFileExists('.env', false),
$this->callFileExists('.env.development'),

$this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')),

$this->callFilePutContent('database/migrations/2018_11_11_111111_add_default_admin.php', $this->getFixture('users_default_admin_default_credentials.php')),
$this->callFilePutContent('database/migrations/2018_11_11_111111_add_telescope_admin.php', $this->getFixture('telescope_users_default_credentials.php')),
$this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('nova_users_default_credentials.php')),
$this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')),
$this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND),

$this->callShellExec('composer require laravel/ui --ansi'),
$this->callShellExec('composer require ronasit/laravel-helpers --ansi'),
$this->callShellExec('composer require ronasit/laravel-swagger --ansi'),
$this->callShellExec('php artisan vendor:publish --provider="RonasIT\AutoDoc\AutoDocServiceProvider" --ansi'),
$this->callShellExec('composer require --dev ronasit/laravel-entity-generator --ansi'),
$this->callShellExec('composer require --dev laravel/pint --ansi'),
$this->callShellExec('php artisan vendor:publish --tag=pint-config --ansi'),
$this->callShellExec('composer require --dev brainmaestro/composer-git-hooks --ansi'),
$this->callShellExec('./vendor/bin/cghooks update --ansi'),
$this->callShellExec('php artisan lang:publish --ansi'),
$this->callShellExec('composer require ronasit/laravel-telescope-extension --ansi'),
$this->callShellExec('php artisan telescope:install --ansi'),
$this->callShellExec('php artisan vendor:publish --tag=initializator-web-login --force'),
$this->callShellExec('php artisan migrate --ansi --force'),
);

$this->mockNativeFunction(
'RonasIT\ProjectInitializator\Generators',
$this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')),
$this->callFilePutContent('README.md', $this->getFixture('none_auth_default_admins_credentials_readme.md')),
);

$consoleApplication = new Application();
$consoleApplication->add(app(InitCommand::class));

$command = $consoleApplication->find('init');
$command->setLaravel(app());

$tester = new CommandTester($command);
$tester->setInputs($this->getJsonFixture('none_auth_type_admin_default_credentials_user_inputs'));

$tester->execute([
'command' => $command->getName(),
'application-name' => 'My App',
]);
}

public function testDefaultAdminsCredentialsClerkAuth()
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test method is missing the : void return type declaration. For consistency with other recently added test methods in this file (like testRunWithClerkMobileAppWithPintInstalled and testRunWithClerkAdditionalAdminsWithoutDefaultAdmin), this method should include the return type.

Add : void after the method signature:

public function testDefaultAdminsCredentialsClerkAuth(): void
Suggested change
public function testDefaultAdminsCredentialsClerkAuth()
public function testDefaultAdminsCredentialsClerkAuth(): void

Copilot uses AI. Check for mistakes.
{
$this->mockNativeFunction(
'\Winter\LaravelConfigWriter',
$this->changeEnvFileCall('.env.example', 'env.example.yml', 'env.example_app_name_not_pascal_case.yml'),
$this->changeEnvFileCall('.env.development', 'env.development.yml', 'env.development_app_name_not_pascal_case.yml'),
$this->changeEnvFileCall('.env.development', 'env.development_app_name_not_pascal_case.yml', 'env.development_clerk_credentials_added.yml'),
$this->changeEnvFileCall('.env.example', 'env.example.yml', 'env.example_clerk_credentials_added.yml'),
$this->changeConfigFileCall('config/auto-doc.php', 'auto_doc.php', 'auto_doc_after_changes.php'),
$this->changeConfigFileCall('config/telescope.php', 'telescope_config.php', 'telescope_config_after_initialization.php'),
);

$this->mockNativeFunction(
'RonasIT\ProjectInitializator\Commands',
$this->callFileExists('.env', false),
$this->callFileExists('.env.development'),

$this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')),

$this->callFilePutContent('database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', $this->getFixture('users_add_clerk_id_field_migration.php')),
$this->callFilePutContent('app/Support/Clerk/ClerkUserRepository.php', $this->getFixture('clerk_user_repository.php')),
$this->callFilePutContent('database/migrations/2018_11_11_111111_admins_create_table.php', $this->getFixture('admins_table_migration.php')),
$this->callFilePutContent('database/migrations/2018_11_11_111111_add_default_admin.php', $this->getFixture('admins_add_default_admin_default_credentials.php')),
$this->callGlob(base_path('database/migrations/*_admins_create_table.php'), [base_path('database/migrations/2018_11_11_111111_admins_create_table.php')]),
$this->callFilePutContent('database/migrations/2018_11_11_111111_add_telescope_admin.php', $this->getFixture('admins_add_telescope_admin_default_credentials.php')),
$this->callGlob(base_path('database/migrations/*_admins_create_table.php'), [base_path('database/migrations/2018_11_11_111111_admins_create_table.php')]),
$this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('admins_add_nova_admin_default_credentials.php')),
$this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')),
$this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND),

$this->callShellExec('composer require laravel/ui --ansi'),
$this->callShellExec('composer require ronasit/laravel-helpers --ansi'),
$this->callShellExec('composer require ronasit/laravel-swagger --ansi'),
$this->callShellExec('php artisan vendor:publish --provider="RonasIT\AutoDoc\AutoDocServiceProvider" --ansi'),
$this->callShellExec('composer require --dev ronasit/laravel-entity-generator --ansi'),
$this->callShellExec('composer require --dev laravel/pint --ansi'),
$this->callShellExec('php artisan vendor:publish --tag=pint-config --ansi'),
$this->callShellExec('composer require --dev brainmaestro/composer-git-hooks --ansi'),
$this->callShellExec('./vendor/bin/cghooks update --ansi'),
$this->callShellExec('php artisan lang:publish --ansi'),
$this->callShellExec('composer require ronasit/laravel-clerk --ansi'),
$this->callShellExec('php artisan laravel-clerk:install --ansi'),
$this->callShellExec('composer require ronasit/laravel-telescope-extension --ansi'),
$this->callShellExec('php artisan telescope:install --ansi'),
$this->callShellExec('php artisan vendor:publish --tag=initializator-web-login --force'),
$this->callShellExec('php artisan migrate --ansi --force'),
);

$this->mockNativeFunction(
'RonasIT\ProjectInitializator\Generators',
$this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')),
$this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')),
$this->callFilePutContent('README.md', $this->getFixture('clerk_auth_default_admins_credentials_readme.md')),
);

$consoleApplication = new Application();
$consoleApplication->add(app(InitCommand::class));

$command = $consoleApplication->find('init');
$command->setLaravel(app());

$tester = new CommandTester($command);
$tester->setInputs($this->getJsonFixture('clerk_auth_type_admin_default_credentials_user_inputs'));

$tester->execute([
'command' => $command->getName(),
'application-name' => 'My App',
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

return new class extends Migration
{
public function up(): void
{
if (!App::environment('testing')) {
DB::table('admins')->insert([
'email' => 'admin@my-app.com',
'password' => Hash::make('123456'),
]);
}
}

public function down(): void
{
if (!App::environment('testing')) {
DB::table('admins')
->where('email', 'admin@my-app.com')
->delete();
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

return new class extends Migration
{
public function up(): void
{
if (!App::environment('testing')) {
DB::table('admins')->insert([
'email' => 'admin.nova@my-app.com',
'password' => Hash::make('123456'),
]);
}
}

public function down(): void
{
if (!App::environment('testing')) {
DB::table('admins')
->where('email', 'admin.nova@my-app.com')
->delete();
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

return new class extends Migration
{
public function up(): void
{
if (!App::environment('testing')) {
DB::table('admins')->insert([
'email' => 'admin.telescope@my-app.com',
'password' => Hash::make('654321'),
]);
}
}

public function down(): void
{
if (!App::environment('testing')) {
DB::table('admins')
->where('email', 'admin.telescope@my-app.com')
->delete();
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# My App

This project implements an API for the My App Web app.

## Project Resources & Contacts

This section provides quick links to various resources and contacts associated
with this project. It's here to streamline your navigation and communication
process, so you can efficiently find what you need or reach out to who you need.

### Resources

Below are links to tools and services used in this project:
- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing article 'a' before 'debug assistant'. Should be "This is a debug assistant for the Laravel framework."

Suggested change
- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later)
- [Laravel Telescope](): This is a debug assistant for the Laravel framework. (will be added later)

Copilot uses AI. Check for mistakes.
- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing article 'an' before 'admin panel'. Should be "This is an admin panel for the Laravel framework."

Suggested change
- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later)
- [Laravel Nova](): This is an admin panel for the Laravel framework. (will be added later)

Copilot uses AI. Check for mistakes.
- [API Documentation](https://mysite.com)

### Contacts

Should you need assistance or have questions, feel free to connect with the following individuals:
- Manager: If you have any high-level project concerns, feel free to get in touch with our project manager. [Connect with Manager](mailto:manager@mail.com)
- Code Owner/Team Lead: For specific questions about the codebase or technical aspects, reach out to our team lead. [Connect with Team Lead](mailto:test@example.com)

Please be mindful of each individual's preferred contact method and office hours.

## Credentials and Access

Default admin access:
- email `admin@my-app.com`
- password `123456`

Laravel Telescope access:
- email `admin.telescope@my-app.com`
- password `654321`

Laravel Nova access:
- email `admin.nova@my-app.com`
- password `123456`

Core auth solution is [Clerk](https://clerk.com) so in `development` environment use any test phones and emails from [this list](https://clerk.com/docs/testing/test-emails-and-phones)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[
"no",
"test@example.com",
"https://mysite.com",
"Web",
"clerk",
"yes",
null,
"123456",
"yes",
"yes",
"no",
"no",
"no",
"no",
"no",
"later",
"later",
"manager@mail.com",
"no",
"no",
"no",
"yes",
"no",
null,
"654321",
"no",
null,
"123456",
"no",
"no",
"no"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# My App

This project implements an API for the My App Web app.

## Project Resources & Contacts

This section provides quick links to various resources and contacts associated
with this project. It's here to streamline your navigation and communication
process, so you can efficiently find what you need or reach out to who you need.

### Resources

Below are links to tools and services used in this project:
- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing article 'a' before 'debug assistant'. Should be "This is a debug assistant for the Laravel framework."

Suggested change
- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later)
- [Laravel Telescope](): This is a debug assistant for the Laravel framework. (will be added later)

Copilot uses AI. Check for mistakes.
- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing article 'an' before 'admin panel'. Should be "This is an admin panel for the Laravel framework."

Suggested change
- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later)
- [Laravel Nova](): This is an admin panel for the Laravel framework. (will be added later)

Copilot uses AI. Check for mistakes.
- [API Documentation](https://mysite.com)

### Contacts

Should you need assistance or have questions, feel free to connect with the following individuals:
- Manager: If you have any high-level project concerns, feel free to get in touch with our project manager. [Connect with Manager](mailto:manager@mail.com)
- Code Owner/Team Lead: For specific questions about the codebase or technical aspects, reach out to our team lead. [Connect with Team Lead](mailto:test@example.com)

Please be mindful of each individual's preferred contact method and office hours.

## Credentials and Access

Default admin access:
- email `admin@my-app.com`
- password `123456`

Laravel Telescope access:
- email `admin.telescope@my-app.com`
- password `654321`

Laravel Nova access:
- email `admin.nova@my-app.com`
- password `123456`
Loading
Loading