diff --git a/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php b/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php index 446a1e31..1c6971bf 100644 --- a/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php +++ b/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php @@ -77,6 +77,28 @@ class DatabaseConfigurationController extends Controller break; + case 'mariadb': + $databaseData = [ + 'database_connection' => 'mariadb', + 'database_host' => '127.0.0.1', + 'database_port' => 3306, + ]; + + break; + + default: + // Never return an empty config: the wizard picks its form from + // database_connection, so an unrecognised driver used to render + // a blank step with no way forward. Echo it back with the + // server defaults instead. + $databaseData = [ + 'database_connection' => $connection, + 'database_host' => '127.0.0.1', + 'database_port' => 3306, + ]; + + break; + } return response()->json([ diff --git a/resources/scripts/admin/views/installation/Step3DatabaseConfig.vue b/resources/scripts/admin/views/installation/Step3DatabaseConfig.vue index 1c442078..619365a4 100644 --- a/resources/scripts/admin/views/installation/Step3DatabaseConfig.vue +++ b/resources/scripts/admin/views/installation/Step3DatabaseConfig.vue @@ -28,6 +28,10 @@ export default { Mysql, Pgsql, Sqlite, + // Resolved by . MariaDB takes the same + // fields as MySQL, so it reuses that form rather than duplicating it — + // without an entry here the step renders blank. See InvoiceShelf/docker#79. + Mariadb: Mysql, }, emits: ['next'], diff --git a/resources/scripts/admin/views/installation/database/MysqlDatabase.vue b/resources/scripts/admin/views/installation/database/MysqlDatabase.vue index a0b422f8..5c945df6 100644 --- a/resources/scripts/admin/views/installation/database/MysqlDatabase.vue +++ b/resources/scripts/admin/views/installation/database/MysqlDatabase.vue @@ -133,7 +133,7 @@ const props = defineProps({ const emit = defineEmits(['submit-data', 'on-change-driver']) -const connections = reactive(['sqlite', 'mysql', 'pgsql']) +const connections = reactive(['sqlite', 'mysql', 'mariadb', 'pgsql']) const { t } = useI18n() const utils = inject('utils') diff --git a/resources/scripts/admin/views/installation/database/PgsqlDatabase.vue b/resources/scripts/admin/views/installation/database/PgsqlDatabase.vue index 2c0667a5..52745140 100644 --- a/resources/scripts/admin/views/installation/database/PgsqlDatabase.vue +++ b/resources/scripts/admin/views/installation/database/PgsqlDatabase.vue @@ -153,7 +153,7 @@ const props = defineProps({ const emit = defineEmits(['submit-data', 'on-change-driver']) -const connections = reactive(['sqlite', 'mysql', 'pgsql']) +const connections = reactive(['sqlite', 'mysql', 'mariadb', 'pgsql']) const { t } = useI18n() const utils = inject('utils') diff --git a/resources/scripts/admin/views/installation/database/SqliteDatabase.vue b/resources/scripts/admin/views/installation/database/SqliteDatabase.vue index c4b2e3f0..f7b8dfc7 100644 --- a/resources/scripts/admin/views/installation/database/SqliteDatabase.vue +++ b/resources/scripts/admin/views/installation/database/SqliteDatabase.vue @@ -97,7 +97,7 @@ const props = defineProps({ const emit = defineEmits(['submit-data', 'on-change-driver']) -const connections = reactive(['sqlite', 'mysql', 'pgsql']) +const connections = reactive(['sqlite', 'mysql', 'mariadb', 'pgsql']) const { t } = useI18n() const utils = inject('utils') diff --git a/tests/Feature/Installation/DatabaseConfigurationTest.php b/tests/Feature/Installation/DatabaseConfigurationTest.php new file mode 100644 index 00000000..07d436a6 --- /dev/null +++ b/tests/Feature/Installation/DatabaseConfigurationTest.php @@ -0,0 +1,58 @@ +assertOk(); + + expect($response->json('config.database_connection'))->toBe($connection); +})->with([ + 'mysql', + 'mariadb', + 'pgsql', + 'sqlite', +]); + +test('sqlite is told where its database file lives', function () { + $response = getJson('/api/v1/installation/database/config?connection=sqlite'); + + $response->assertOk(); + + expect($response->json('config.database_name'))->not->toBeEmpty(); +}); + +test('server-based drivers are given a host and port to prefill', function (string $connection) { + $response = getJson("/api/v1/installation/database/config?connection={$connection}"); + + expect($response->json('config.database_host'))->not->toBeEmpty() + ->and($response->json('config.database_port'))->not->toBeEmpty(); +})->with([ + 'mysql', + 'mariadb', + 'pgsql', +]); + +/** + * A driver we do not recognise must still produce something the wizard can + * render, rather than the empty config that caused #79. + */ +test('an unrecognised driver still returns a renderable config', function () { + $response = getJson('/api/v1/installation/database/config?connection=cockroach'); + + $response->assertOk(); + + expect($response->json('config.database_connection'))->toBe('cockroach') + ->and($response->json('config'))->not->toBeEmpty(); +});