44import pathlib
55
66import pytest
7+ import sqlalchemy
78from click .testing import CliRunner
89
910from microSALT .cli import root
10- from microSALT .config import MicroSALTConfig
11+ from microSALT .config import (
12+ Containers ,
13+ Database ,
14+ Folders ,
15+ MicroSALTConfig ,
16+ PasteurCredentials ,
17+ PubMLSTCredentials ,
18+ Regex ,
19+ Singularity ,
20+ SlurmHeader ,
21+ Threshold ,
22+ )
23+ from microSALT .store .orm_models import Base
1124
1225
1326@pytest .fixture
@@ -18,6 +31,48 @@ def config_file(config: MicroSALTConfig, tmp_path: pathlib.Path) -> pathlib.Path
1831 return path
1932
2033
34+ @pytest .fixture
35+ def setup_config (tmp_path : pathlib .Path ) -> MicroSALTConfig :
36+ """Fresh MicroSALTConfig whose directories do not yet exist — used to test `setup`."""
37+ from importlib .resources import files as resource_files
38+
39+ base = tmp_path / "microsalt"
40+ base .mkdir ()
41+ cfg = MicroSALTConfig (
42+ slurm_header = SlurmHeader (time = "1:00:00" , threads = "4" , qos = "normal" ,
43+ job_prefix = "MLST" , project = "test" , type = "core" ),
44+ regex = Regex (mail_recipient = "test@test.com" , file_pattern = ".*" , verified_organisms = []),
45+ folders = Folders (
46+ results = str (base / "results" ),
47+ reports = str (base / "reports" ),
48+ log_file = str (base / "microsalt.log" ),
49+ seqdata = str (base / "seqdata" ),
50+ profiles = str (base / "profiles" ),
51+ references = str (base / "references" ),
52+ resistances = str (base / "resistances" ),
53+ genomes = str (base / "genomes" ),
54+ credentials = str (base / "credentials" ),
55+ adapters = str (base / "adapters" ),
56+ ),
57+ database = Database (SQLALCHEMY_DATABASE_URI = f"sqlite:///{ base / 'microsalt.db' } " ),
58+ threshold = Threshold (),
59+ pubmlst = PubMLSTCredentials (),
60+ pasteur = PasteurCredentials (),
61+ singularity = Singularity (),
62+ containers = Containers (),
63+ )
64+ cfg .folders .expec = str (resource_files ("microSALT" ).joinpath ("unique_references" , "ExPEC.fsa" ))
65+ return cfg
66+
67+
68+ @pytest .fixture
69+ def setup_config_file (setup_config : MicroSALTConfig , tmp_path : pathlib .Path ) -> pathlib .Path :
70+ """Write the setup_config to a JSON file and return its path."""
71+ path = tmp_path / "config.json"
72+ path .write_text (setup_config .model_dump_json ())
73+ return path
74+
75+
2176def invoke_root (config_file : pathlib .Path , * args : str ):
2277 """Invoke the root CLI group with the test config and additional arguments."""
2378 runner = CliRunner ()
@@ -48,55 +103,22 @@ def test_config_fields_propagated(config: MicroSALTConfig, config_file: pathlib.
48103 assert loaded .slurm_header .project == config .slurm_header .project
49104
50105
51- def test_setup_command (tmp_path ):
52- """setup command creates the configured directories without error."""
53- from importlib .resources import files as resource_files
54-
55- from microSALT .config import (
56- Containers ,
57- Database ,
58- Folders ,
59- PasteurCredentials ,
60- PubMLSTCredentials ,
61- Regex ,
62- Singularity ,
63- SlurmHeader ,
64- Threshold ,
65- )
66-
67- base = tmp_path / "microsalt"
68- base .mkdir ()
69-
70- cfg = MicroSALTConfig (
71- slurm_header = SlurmHeader (time = "1:00:00" , threads = "4" , qos = "normal" ,
72- job_prefix = "MLST" , project = "test" , type = "core" ),
73- regex = Regex (mail_recipient = "test@test.com" , file_pattern = ".*" , verified_organisms = []),
74- folders = Folders (
75- results = str (base / "results" ),
76- reports = str (base / "reports" ),
77- log_file = str (base / "microsalt.log" ),
78- seqdata = str (base / "seqdata" ),
79- profiles = str (base / "profiles" ),
80- references = str (base / "references" ),
81- resistances = str (base / "resistances" ),
82- genomes = str (base / "genomes" ),
83- credentials = str (base / "credentials" ),
84- adapters = str (base / "adapters" ),
85- ),
86- database = Database (SQLALCHEMY_DATABASE_URI = f"sqlite:///{ base } /microsalt.db" ),
87- threshold = Threshold (),
88- pubmlst = PubMLSTCredentials (),
89- pasteur = PasteurCredentials (),
90- singularity = Singularity (),
91- containers = Containers (),
92- )
93- cfg .folders .expec = str (resource_files ("microSALT" ).joinpath ("unique_references" , "ExPEC.fsa" ))
106+ def test_setup_command (setup_config : MicroSALTConfig , setup_config_file : pathlib .Path ):
107+ """setup command creates the configured directories and reports success."""
108+ result = invoke_root (setup_config_file , "setup" )
109+ assert result .exit_code == 0 , result .output
110+ assert "Directory setup complete" in result .output
111+ assert "Database tables created" in result .output
112+ assert pathlib .Path (setup_config .folders .results ).exists ()
113+ assert pathlib .Path (setup_config .folders .reports ).exists ()
94114
95- config_path = tmp_path / "config.json"
96- config_path .write_text (cfg .model_dump_json ())
97115
98- result = invoke_root (config_path , "setup" )
116+ def test_setup_command_creates_tables (setup_config : MicroSALTConfig , setup_config_file : pathlib .Path ):
117+ """setup command creates every ORM-defined table in the database."""
118+ result = invoke_root (setup_config_file , "setup" )
99119 assert result .exit_code == 0 , result .output
100- assert "Directory setup complete" in result .output
101- assert (base / "results" ).exists ()
102- assert (base / "reports" ).exists ()
120+
121+ engine = sqlalchemy .create_engine (setup_config .database .SQLALCHEMY_DATABASE_URI )
122+ created = sqlalchemy .inspect (engine ).get_table_names ()
123+ expected = set (Base .metadata .tables .keys ())
124+ assert expected == set (created ), f"Missing tables: { expected - set (created )} "
0 commit comments