Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,7 @@ def compile_table_exists(self, table, database=None, schema=None):
return f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'"

def compile_column_exists(self, table, column):
return (
f"SELECT column_name FROM information_schema.columns WHERE table_name='{table}' and column_name='{column}'"
)
return f"SELECT name FROM pragma_table_info('{table}') WHERE name='{column}'"

def compile_get_all_tables(self, database, schema=None):
return "SELECT name FROM sqlite_master WHERE type='table'"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi_startkit.masoniteorm.seeders import Seeder

from .recorder import CALLS
from ...models import SeededUser


class DatabaseSeeder(Seeder):
async def run(self):
CALLS.append(("database", self.connection))
await SeededUser.create({"name": "database-seeder"})

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi_startkit.masoniteorm.seeders import Seeder

from .recorder import CALLS
from ...models import SeededUser


class SampleSeeder(Seeder):
async def run(self):
CALLS.append(("sample", self.connection))
await SeededUser.create({"name": "sample-seeder"})
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi_startkit.masoniteorm.seeders import Seeder

from .recorder import CALLS
from ...models import SeededUser


class SpecialSeeder(Seeder):
async def run(self):
CALLS.append(("special", self.connection))
await SeededUser.create({"name": "special-seeder"})
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi_startkit.masoniteorm.seeders import Seeder

from .recorder import CALLS
from ...models import SeededUser


class UserTableSeeder(Seeder):
async def run(self):
CALLS.append(("user_table", self.connection))
await SeededUser.create({"name": "user-table-seeder"})
10 changes: 10 additions & 0 deletions fastapi_startkit/tests/masoniteorm/commands/fixtures/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from fastapi_startkit.masoniteorm.models.model import Model


class SeededUser(Model):
"""Real model backing the sqlite table the fixture seeders write into."""

__table__ = "seed_users"
__timestamps__ = False

name: str
142 changes: 56 additions & 86 deletions fastapi_startkit/tests/masoniteorm/commands/test_db_seed_command.py
Original file line number Diff line number Diff line change
@@ -1,127 +1,101 @@
import io
import asyncio
import unittest
from contextlib import redirect_stdout
from unittest import mock

from cleo.testers.command_tester import CommandTester

from fastapi_startkit.masoniteorm.commands.DBSeedCommand import DBSeedCommand

from .fixtures.databases.seeders.recorder import CALLS
from .fixtures.app import create_app, DB_PATH
from .fixtures.models import SeededUser

FIXTURE_SEED_PATH = "tests.masoniteorm.commands.fixtures.databases.seeders"


class TestDBSeedCommand(unittest.TestCase):
def setUp(self):
from .fixtures.app import create_app
@classmethod
def setUpClass(cls):
cls.app = create_app()

self.app = create_app()
CALLS.clear()
def setUp(self):
asyncio.run(self._reset_table())

def tearDown(self):
CALLS.clear()
asyncio.run(self._drop_table())
if DB_PATH.exists():
DB_PATH.unlink()

async def _reset_table(self):
db = self.app.make("db")
await db.clear()
schema = db.get_schema_builder()
await schema.drop_table_if_exists("seed_users")
async with await schema.create("seed_users") as table:
table.id()
table.string("name")

async def _drop_table(self):
db = self.app.make("db")
schema = db.get_schema_builder()
await schema.drop_table_if_exists("seed_users")
await db.clear()

def _run(self, args=""):
tester = CommandTester(DBSeedCommand())
tester.execute(args)
return tester.io.fetch_output()

def _run_app(self, args=""):
buffer = io.StringIO()
with redirect_stdout(buffer):
self.app.run("db:seed", args)
return buffer.getvalue()
def _seeded_names(self):
return asyncio.run(self._fetch_names())

@staticmethod
async def _fetch_names():
rows = await SeededUser.all()
return sorted(row.name for row in rows)

# -- option/argument resolution, exercised against a mocked Seeder --
# -- behavior is proven by the rows the real Seeder + real fixture seeder
# classes write into a real sqlite table, not by console output --

def test_runs_database_seeder_by_default(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
output = self._run("")
self._run(f"--directory {FIXTURE_SEED_PATH} --connection sqlite")

self.assertIn("Database Seeder seeded!", output)
MockSeeder.assert_called_once_with(seed_path="databases/seeders", connection="default")
MockSeeder.return_value.run_database_seed.assert_awaited_once_with()
MockSeeder.return_value.run_specific_seed.assert_not_awaited()
self.assertEqual(self._seeded_names(), ["database-seeder"])

def test_seeds_specific_table_from_argument(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
output = self._run("posts")
self._run(f"user --directory {FIXTURE_SEED_PATH} --connection sqlite")

self.assertIn("PostsTableSeeder seeded!", output)
MockSeeder.return_value.run_specific_seed.assert_awaited_once_with("posts_table_seeder.PostsTableSeeder")
self.assertEqual(self._seeded_names(), ["user-table-seeder"])

def test_class_option_resolves_plain_class_name(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
output = self._run("--class PostSeeder")
self._run(f"--directory {FIXTURE_SEED_PATH} --class SampleSeeder --connection sqlite")

self.assertIn("PostSeeder seeded!", output)
MockSeeder.return_value.run_specific_seed.assert_awaited_once_with("post_seeder.PostSeeder")
self.assertEqual(self._seeded_names(), ["sample-seeder"])

def test_class_option_resolves_table_seeder_suffix(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
output = self._run("--class PostTableSeeder")
self._run(f"--directory {FIXTURE_SEED_PATH} --class UserTableSeeder --connection sqlite")

self.assertIn("PostTableSeeder seeded!", output)
MockSeeder.return_value.run_specific_seed.assert_awaited_once_with("post_table_seeder.PostTableSeeder")
self.assertEqual(self._seeded_names(), ["user-table-seeder"])

def test_class_option_accepts_dotted_path(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
output = self._run("--class custom.MySeeder")

self.assertIn("MySeeder seeded!", output)
MockSeeder.return_value.run_specific_seed.assert_awaited_once_with("custom.MySeeder")
self._run(f"--directory {FIXTURE_SEED_PATH} --class special_seeder.SpecialSeeder --connection sqlite")

def test_connection_and_directory_options_are_forwarded(self):
with mock.patch("fastapi_startkit.masoniteorm.seeders.Seeder", autospec=True) as MockSeeder:
self._run("--connection sqlite --directory db/seeds")

MockSeeder.assert_called_once_with(seed_path="db/seeds", connection="sqlite")

# -- end-to-end, driven through the registered console app against real fixture seeders --

def test_runs_database_seeder_by_default_via_app(self):
output = self._run_app(f"--directory {FIXTURE_SEED_PATH} --connection sqlite")

self.assertIn("Database Seeder seeded!", output)
self.assertEqual(CALLS, [("database", "sqlite")])
self.assertEqual(self._seeded_names(), ["special-seeder"])

def test_runs_seeder_for_table_argument_via_app(self):
output = self._run_app(f"user --directory {FIXTURE_SEED_PATH} --connection sqlite")
def test_class_option_takes_precedence_over_table_argument(self):
self._run(f"user --directory {FIXTURE_SEED_PATH} --class SampleSeeder --connection sqlite")

self.assertIn("UserTableSeeder seeded!", output)
self.assertEqual(CALLS, [("user_table", "sqlite")])
self.assertEqual(self._seeded_names(), ["sample-seeder"])

def test_runs_seeder_for_class_option_without_table_suffix_via_app(self):
output = self._run_app(f"--directory {FIXTURE_SEED_PATH} --class SampleSeeder --connection sqlite")
def test_uses_default_connection_when_not_specified(self):
self._run(f"--directory {FIXTURE_SEED_PATH}")

self.assertIn("SampleSeeder seeded!", output)
self.assertEqual(CALLS, [("sample", "sqlite")])
self.assertEqual(self._seeded_names(), ["database-seeder"])

def test_runs_seeder_for_class_option_with_table_suffix_via_app(self):
output = self._run_app(f"--directory {FIXTURE_SEED_PATH} --class UserTableSeeder --connection sqlite")
def test_success_message_names_the_seeder(self):
# Minimal, secondary output check -- the user-facing message contract,
# not a substitute for the row assertions above.
output = self._run(f"--directory {FIXTURE_SEED_PATH} --connection sqlite")

self.assertIn("UserTableSeeder seeded!", output)
self.assertEqual(CALLS, [("user_table", "sqlite")])

def test_runs_seeder_for_fully_qualified_class_option_via_app(self):
output = self._run_app(
f"--directory {FIXTURE_SEED_PATH} --class special_seeder.SpecialSeeder --connection sqlite"
)

self.assertIn("SpecialSeeder seeded!", output)
self.assertEqual(CALLS, [("special", "sqlite")])

def test_class_option_takes_precedence_over_table_argument_via_app(self):
output = self._run_app(f"user --directory {FIXTURE_SEED_PATH} --class SampleSeeder --connection sqlite")

self.assertIn("SampleSeeder seeded!", output)
self.assertEqual(CALLS, [("sample", "sqlite")])

def test_uses_default_connection_option_via_app(self):
self._run_app(f"--directory {FIXTURE_SEED_PATH}")

self.assertEqual(CALLS, [("database", "default")])
self.assertIn("Database Seeder seeded!", output)

# -- error paths: driven directly through CommandTester, since the console
# application catches command exceptions instead of propagating them --
Expand All @@ -133,7 +107,3 @@ def test_raises_when_seeder_class_cannot_be_found(self):
def test_raises_when_database_seeder_missing_from_directory(self):
with self.assertRaises(ValueError):
self._run("--directory tests.masoniteorm.commands.fixtures.databases.migrations --connection sqlite")


if __name__ == "__main__":
unittest.main()
Loading
Loading