1from pathlib import Path
2
3from qbpm import profiles
4from qbpm.config import Config
5from qbpm.profiles import Profile
6
7from . import no_homedir_fixture # noqa: F401
8
9
10def check_is_empty(path: Path):
11 assert len(list(path.iterdir())) == 0
12
13
14def check_empty_profile(profile: Profile | None):
15 assert profile
16 config_dir = profile.root / "config"
17 assert list(profile.root.iterdir()) == [config_dir]
18 assert list(config_dir.iterdir()) == []
19
20
21def check_new_profile(profile: Profile):
22 assert profile
23 config_dir = profile.root / "config"
24 assert list(profile.root.iterdir()) == [config_dir]
25 assert list(config_dir.iterdir()) == [config_dir / "config.py"]
26
27
28def test_set_profile(tmp_path: Path):
29 assert Profile("test", tmp_path).root == tmp_path / "test"
30
31
32def test_create_profile(tmp_path: Path):
33 profile = Profile("test", tmp_path)
34 assert profiles.create_profile(profile)
35 assert list(tmp_path.iterdir()) == [profile.root]
36 check_empty_profile(profile)
37
38
39def test_create_profile_conflict(tmp_path: Path):
40 (tmp_path / "test").touch()
41 profile = Profile("test", tmp_path)
42 assert not profiles.create_profile(profile)
43
44
45def test_create_profile_parent(tmp_path: Path):
46 profile = Profile("../test", tmp_path / "profiles")
47 assert not profiles.create_profile(profile)
48 assert not (tmp_path / "test").exists()
49
50
51def test_create_profile_nested_conflict(tmp_path: Path):
52 assert profiles.create_profile(Profile("test", tmp_path))
53 assert not profiles.create_profile(Profile("test/a", tmp_path))
54
55
56def test_create_config(tmp_path: Path):
57 (tmp_path / "config.py").touch()
58 profile = Profile("test", tmp_path)
59 config_dir = profile.root / "config"
60 config_dir.mkdir(parents=True)
61 profiles.create_config(profile, tmp_path, "{source_config_py}")
62 config = config_dir / "config.py"
63 assert list(config_dir.iterdir()) == [config]
64 assert str(tmp_path / "config.py") in config.read_text()
65
66
67def test_overwrite_config(tmp_path: Path):
68 (tmp_path / "config.py").touch()
69 profile = Profile("test", tmp_path)
70 url = "http://example.com"
71 config_dir = profile.root / "config"
72 config_dir.mkdir(parents=True)
73 config = config_dir / "config.py"
74 backup = config_dir / "config.py.bak"
75 profiles.create_config(profile, tmp_path, "")
76 profiles.create_config(profile, tmp_path, "", url, True)
77 assert set(config_dir.iterdir()) == {config, backup}
78 assert url in config.read_text()
79 assert url not in backup.read_text()
80
81
82def test_link_autoconfig(tmp_path: Path):
83 profile = Profile("test", tmp_path)
84 config_dir = profile.root / "config"
85 config_dir.mkdir(parents=True)
86 (tmp_path / "autoconfig.yml").touch()
87 profiles.link_autoconfig(profile, tmp_path, False)
88 config = config_dir / "autoconfig.yml"
89 assert list(config_dir.iterdir()) == [config]
90 assert config.resolve().parent == tmp_path
91
92
93def test_autoconfig_present(tmp_path: Path):
94 profile = Profile("test", tmp_path)
95 config_dir = profile.root / "config"
96 config_dir.mkdir(parents=True)
97 (tmp_path / "autoconfig.yml").touch()
98 profiles.link_autoconfig(profile, tmp_path, False)
99 profiles.link_autoconfig(profile, tmp_path, False)
100 config = config_dir / "autoconfig.yml"
101 assert list(config_dir.iterdir()) == [config]
102 assert config.resolve().parent == tmp_path
103
104
105def test_overwrite_autoconfig(tmp_path: Path):
106 profile = Profile("test", tmp_path)
107 config_dir = profile.root / "config"
108 config_dir.mkdir(parents=True)
109 (config_dir / "autoconfig.yml").touch()
110 (tmp_path / "autoconfig.yml").touch()
111 profiles.link_autoconfig(profile, tmp_path, True)
112 config = config_dir / "autoconfig.yml"
113 assert set(config_dir.iterdir()) == {config, config_dir / "autoconfig.yml.bak"}
114 assert config.resolve().parent == tmp_path
115
116
117def test_new_profile(tmp_path: Path):
118 (tmp_path / "config.py").touch()
119 profile = Profile("test", tmp_path / "test")
120 config = Config.load(None)
121 config.qutebrowser_config_directory = tmp_path
122 config.generate_desktop_file = False
123 assert profiles.new_profile(profile, config)
124 check_new_profile(profile)
125
126
127def test_new_profile_autoconfig(tmp_path: Path):
128 (tmp_path / "autoconfig.yml").touch()
129 profile = Profile("test", tmp_path / "test")
130 config = Config.load(None)
131 config.qutebrowser_config_directory = tmp_path
132 config.generate_desktop_file = False
133 config.symlink_autoconfig = True
134 profiles.new_profile(profile, config)
135 config_dir = profile.root / "config"
136 assert set(config_dir.iterdir()) == {config_dir / "autoconfig.yml"}
137
138
139def test_new_profile_both(tmp_path: Path):
140 (tmp_path / "config.py").touch()
141 (tmp_path / "autoconfig.yml").touch()
142 profile = Profile("test", tmp_path / "test")
143 config = Config.load(None)
144 config.qutebrowser_config_directory = tmp_path
145 config.generate_desktop_file = False
146 config.symlink_autoconfig = True
147 profiles.new_profile(profile, config)
148 assert len(set((profile.root / "config").iterdir())) == 2 # noqa: PLR2004
149
150
151def test_config_template(tmp_path: Path):
152 (tmp_path / "config.py").touch()
153 profile = Profile("test", tmp_path)
154 config_dir = profile.root / "config"
155 config_dir.mkdir(parents=True)
156 template = "# Profile: {profile_name}\nconfig.source('{source_config_py}')"
157 profiles.create_profile(profile)
158 profiles.create_config(profile, tmp_path, template)
159 config_content = (profile.root / "config" / "config.py").read_text()
160 assert "# Profile: test" in config_content
161 assert f"config.source('{tmp_path / 'config.py'}')" in config_content
162
163
164def test_missing_qb_config(tmp_path: Path):
165 profile = Profile("test", tmp_path / "test")
166 config = Config.load(None)
167 config.qutebrowser_config_directory = tmp_path
168 config.generate_desktop_file = False
169 assert not profiles.new_profile(profile, config)
170 config.qutebrowser_config_directory = tmp_path / "nonexistent"
171 assert not profiles.new_profile(profile, config)