Skip to content

Commit e94b88e

Browse files
authored
Reduce test boilerplate with fixtures (zeusops#19)
1 parent 6b1b196 commit e94b88e

File tree

7 files changed

+70
-51
lines changed

7 files changed

+70
-51
lines changed

features/reforger_current_mission.feature

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ Scenario: Show currently active mission
1111
And "mission1.json" is set as the active mission
1212
When Zeus calls "/current-mission"
1313
Then "mission1" is displayed
14+
15+
Scenario: Broken mission link produces an error
16+
Given "mission1.json" is set as the active mission
17+
And file "mission1.json" does not exist in the mission directory
18+
When Zeus calls "/current-mission"
19+
Then an error about a missing config is raised

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Configure tests"""
22

3-
from tests.fixtures import config_gen, mission_dir
3+
from tests.fixtures import base_config, mission_dir
44

5-
__all__ = ["mission_dir", "config_gen"]
5+
__all__ = ["mission_dir", "base_config"]

tests/fixtures.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
import pytest
77

88
from zeusops_bot.models import ConfigFile, ModDetail
9-
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator
109

11-
BASE_CONFIG: ConfigFile = {"game": {"scenarioId": "old-value", "mods": []}}
10+
BASE_CONFIG: ConfigFile = {
11+
"game": {
12+
"scenarioId": "old-value",
13+
"mods": [
14+
{"modId": "5EB744C5F42E0800", "name": "ACE Chopping", "version": "1.2.0"}
15+
],
16+
}
17+
}
1218

1319
MODLIST_DICT: list[ModDetail] = [
1420
{"modId": "595F2BF2F44836FB", "name": "RHS - Status Quo", "version": "0.10.4075"},
@@ -48,11 +54,8 @@ def mission_dir(tmp_path: Path) -> Path:
4854

4955

5056
@pytest.fixture
51-
def config_gen(tmp_path: Path, mission_dir: Path) -> ReforgerConfigGenerator:
57+
def base_config(tmp_path: Path) -> Path:
5258
"""Reforger config generator"""
5359
source_file = tmp_path / "source.json"
5460
source_file.write_text(json.dumps(BASE_CONFIG))
55-
gen = ReforgerConfigGenerator(
56-
base_config_file=source_file, target_folder=mission_dir
57-
)
58-
return gen
61+
return source_file

tests/test_current_mission.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator, as_config_file
1515

1616

17-
def test_current_mission(mission_dir: Path, config_gen: ReforgerConfigGenerator):
17+
def test_current_mission(mission_dir: Path, base_config: Path):
1818
"""Scenario: Show currently active mission"""
1919
# Given file "mission1.json" exists in the mission directory
2020
mission_name = "mission1"
2121
as_config_file(mission_dir, mission_name).touch()
22+
config_gen = ReforgerConfigGenerator(
23+
base_config_file=base_config, target_folder=mission_dir
24+
)
2225

2326
# And "mission1.json" is set as the active mission
2427
config_gen.zeus_set_mission(mission_name)
@@ -28,13 +31,21 @@ def test_current_mission(mission_dir: Path, config_gen: ReforgerConfigGenerator)
2831
assert result == mission_name, "Should match previously set mission name"
2932

3033

31-
def test_broken_link(mission_dir: Path, config_gen: ReforgerConfigGenerator):
32-
"""Test that a broken link as active mission raises an error"""
34+
def test_broken_link(mission_dir: Path, base_config: Path):
35+
"""Scenario: Broken mission link produces an error"""
36+
# Given "mission1.json" is set as the active mission
3337
mission_name = "mission1"
3438
config_file = as_config_file(mission_dir, mission_name)
3539
config_file.touch()
3640

41+
config_gen = ReforgerConfigGenerator(
42+
base_config_file=base_config, target_folder=mission_dir
43+
)
3744
config_gen.zeus_set_mission(mission_name)
45+
46+
# And file "mission1.json" does not exist in the mission directory
3847
config_file.unlink()
48+
# When Zeus calls "/current-mission"
3949
with pytest.raises(ConfigFileNotFound):
4050
config_gen.current_mission()
51+
# Then an error about a missing config is raised

tests/test_list_missions.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import pytest
1212

13-
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator
13+
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator, as_config_file
1414

1515

1616
@pytest.mark.parametrize(
@@ -27,15 +27,18 @@
2727
ids=["two missions", "empty", "non-json extra"],
2828
)
2929
def test_list_missions(
30+
base_config: Path,
3031
mission_dir: Path,
31-
config_gen: ReforgerConfigGenerator,
3232
filenames: list[str],
3333
mission_names: list[str],
3434
):
3535
"""Scenario: List uploaded missions"""
3636
# Given files "mission1.json" and "mission2.json" exist in the mission directory
3737
for filename in filenames:
38-
(mission_dir / filename).with_suffix(".json").touch()
38+
as_config_file(mission_dir, filename).touch()
39+
config_gen = ReforgerConfigGenerator(
40+
base_config_file=base_config, target_folder=mission_dir
41+
)
3942
# When Zeus calls "/zeus-list"
4043
result: list[str] = config_gen.list_missions()
4144
# Then a list of mission names is returned

tests/test_set_mission.py

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,53 @@
11
"""Validate the set-mission command"""
22

33
import json
4+
from pathlib import Path
45

56
from tests.fixtures import BASE_CONFIG
67
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator, as_config_file
78

89

9-
def test_load_mission(tmp_path):
10+
def test_load_mission(base_config: Path, mission_dir: Path):
1011
"""Scenario: Load mission from previous upload"""
1112
# Given a Zeusops mission was uploaded already under <filename>
12-
config_base = tmp_path / "reforger_configs"
1313
filename = "Jib_20250228"
14-
uploaded_conf_path = as_config_file(config_base, filename)
15-
uploaded_conf_path.parent.mkdir(parents=True, exist_ok=True)
16-
gen = ReforgerConfigGenerator(
17-
base_config_file=uploaded_conf_path, target_folder=config_base
18-
)
14+
uploaded_conf_path = as_config_file(mission_dir, filename)
1915
uploaded_conf_path.write_text(json.dumps(BASE_CONFIG))
16+
config_gen = ReforgerConfigGenerator(
17+
base_config_file=base_config, target_folder=mission_dir
18+
)
2019
# When Zeus calls "/zeus-set-mission" with <filename>
21-
base_conf = tmp_path / "base.json"
22-
base_conf.write_text(json.dumps(BASE_CONFIG))
23-
gen.zeus_set_mission(filename)
20+
config_gen.zeus_set_mission(filename)
2421
# Then a symbolic link is created from "current-config.json" to <filename>
25-
target = config_base / "current-config.json"
22+
target = mission_dir / "current-config.json"
2623
assert target.exists(), "Should have created latest config symlink"
2724
assert target.is_symlink(), "Target config should be a symlink"
2825
assert target.readlink() == uploaded_conf_path.relative_to(
29-
config_base
26+
mission_dir
3027
), "Target should point to uploaded file"
3128

3229

33-
def test_load_mission_twice(tmp_path):
30+
def test_load_mission_twice(base_config: Path, mission_dir: Path):
3431
"""Scenario: Load two missions back to back"""
3532
# Given a Zeusops mission was uploaded already under <filename>
36-
config_base = tmp_path / "reforger_configs"
3733
filename = "Jib_20250228"
38-
uploaded_conf_path = as_config_file(config_base, filename)
39-
uploaded_conf_path.parent.mkdir(parents=True, exist_ok=True)
40-
gen = ReforgerConfigGenerator(
41-
base_config_file=uploaded_conf_path, target_folder=config_base
42-
)
34+
uploaded_conf_path = as_config_file(mission_dir, filename)
4335
uploaded_conf_path.write_text(json.dumps(BASE_CONFIG))
36+
config_gen = ReforgerConfigGenerator(
37+
base_config_file=base_config, target_folder=mission_dir
38+
)
4439
# And another Zeusops mission was uploaded already under <filename2>
4540
filename2 = "Jib_20250229"
46-
uploaded_conf_path2 = as_config_file(config_base, filename2)
41+
uploaded_conf_path2 = as_config_file(mission_dir, filename2)
4742
uploaded_conf_path2.write_text(json.dumps(BASE_CONFIG))
4843
# And Zeus has already called "/zeus-set-mission" with <filename>
49-
gen.zeus_set_mission(filename)
44+
config_gen.zeus_set_mission(filename)
5045
# When Zeus calls "/zeus-set-mission" with <filename2>
51-
gen.zeus_set_mission(filename2)
46+
config_gen.zeus_set_mission(filename2)
5247
# Then a symbolic link is created from "current-config.json" to <filename2>
53-
target = config_base / "current-config.json"
48+
target = mission_dir / "current-config.json"
5449
assert target.exists(), "Should have created latest config symlink"
5550
assert target.is_symlink(), "Target config should be a symlink"
5651
assert target.readlink() == uploaded_conf_path2.relative_to(
57-
config_base
52+
mission_dir
5853
), "Target should point to latest mission set"

tests/test_upload_mission.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@
77
"""
88

99
import json
10+
from pathlib import Path
1011

1112
from tests.fixtures import BASE_CONFIG, MODLIST_DICT, MODLIST_JSON
1213
from zeusops_bot.reforger_config_gen import ReforgerConfigGenerator, extract_mods
1314

1415

15-
def test_upload_edits_files(tmp_path):
16+
def test_upload_edits_files(base_config: Path, mission_dir: Path):
1617
"""Scenario: Upload next mission creates file"""
1718
# Given a Zeusops mission locally ready
1819
# And Zeus specifies <modlist.json>, <scenarioId>, <filename>
1920
scenario_id = "cool-scenario-1"
2021
filename = "Jib_20250228"
21-
dest = tmp_path / "data"
22-
source_file = tmp_path / "source.json"
23-
source_file.write_text(json.dumps(BASE_CONFIG))
24-
gen = ReforgerConfigGenerator(base_config_file=source_file, target_folder=dest)
22+
config_gen = ReforgerConfigGenerator(
23+
base_config_file=base_config, target_folder=mission_dir
24+
)
2525
# When Zeus calls "/zeus-upload"
2626
modlist = extract_mods(MODLIST_JSON)
27-
out_path = gen.zeus_upload(scenario_id, filename, modlist)
27+
out_path = config_gen.zeus_upload(scenario_id, filename, modlist)
2828
# Then a new server config file is created
2929
assert out_path.is_file(), "Should have generated a file on disk"
3030
# And the config file is patched with <modlist.json> and <scenarioId>
@@ -34,18 +34,19 @@ def test_upload_edits_files(tmp_path):
3434
assert config["game"]["mods"][0] == MODLIST_DICT[0]
3535

3636

37-
def test_upload_edits_files_without_modlist(tmp_path):
37+
def test_upload_edits_files_without_modlist(base_config: Path, mission_dir: Path):
3838
"""Scenario: Upload next mission without modlist"""
3939
# Given a Zeusops mission locally ready
4040
# And Zeus specifies <scenarioId>, <filename>
4141
scenario_id = "cool-scenario-1"
4242
filename = "Jib_20250228"
43-
dest = tmp_path / "data"
44-
source_file = tmp_path / "source.json"
45-
source_file.write_text(json.dumps(BASE_CONFIG))
46-
gen = ReforgerConfigGenerator(base_config_file=source_file, target_folder=dest)
43+
config_gen = ReforgerConfigGenerator(
44+
base_config_file=base_config, target_folder=mission_dir
45+
)
4746
# When Zeus calls "/zeus-upload"
48-
out_path = gen.zeus_upload(scenario_id=scenario_id, filename=filename, modlist=None)
47+
out_path = config_gen.zeus_upload(
48+
scenario_id=scenario_id, filename=filename, modlist=None
49+
)
4950
# Then a new server config file is created
5051
assert out_path.is_file(), "Should have generated a file on disk"
5152
# And the config file is patched with just <scenarioId>

0 commit comments

Comments
 (0)