|
6 | 6 |
|
7 | 7 | from atlassian_local_cli.jira_commands import ( |
8 | 8 | build_jql, |
| 9 | + jira_create, |
9 | 10 | jira_get, |
10 | 11 | jira_my_tasks, |
11 | 12 | jira_transition, |
@@ -173,3 +174,101 @@ def test_invalid_transition_exits(self, mock_create): |
173 | 174 |
|
174 | 175 | with pytest.raises(SystemExit): |
175 | 176 | jira_transition(Namespace(issue_key="PROJ-1", status="invalid")) |
| 177 | + |
| 178 | + |
| 179 | +class TestJiraCreate: |
| 180 | + @patch("atlassian_local_cli.jira_commands.get_config") |
| 181 | + @patch("atlassian_local_cli.jira_commands.create_jira") |
| 182 | + def test_basic_create(self, mock_create, mock_config, capsys): |
| 183 | + mock_config.return_value = MagicMock(jira_url="https://jira.test.com/") |
| 184 | + mock_jira = MagicMock() |
| 185 | + mock_jira.issue_create.return_value = {"key": "PROJ-99"} |
| 186 | + mock_create.return_value = mock_jira |
| 187 | + |
| 188 | + args = Namespace( |
| 189 | + project="PROJ", summary="New task", type="Task", |
| 190 | + description="Short desc", description_file=None, |
| 191 | + priority=None, assignee=None, |
| 192 | + ) |
| 193 | + jira_create(args) |
| 194 | + output = capsys.readouterr().out |
| 195 | + assert "PROJ-99" in output |
| 196 | + assert "New task" in output |
| 197 | + |
| 198 | + fields = mock_jira.issue_create.call_args[1]["fields"] |
| 199 | + assert fields["project"] == {"key": "PROJ"} |
| 200 | + assert fields["summary"] == "New task" |
| 201 | + assert fields["description"] == "Short desc" |
| 202 | + |
| 203 | + @patch("atlassian_local_cli.jira_commands.get_config") |
| 204 | + @patch("atlassian_local_cli.jira_commands.create_jira") |
| 205 | + def test_with_priority_and_assignee(self, mock_create, mock_config): |
| 206 | + mock_config.return_value = MagicMock(jira_url="https://jira.test.com/") |
| 207 | + mock_jira = MagicMock() |
| 208 | + mock_jira.issue_create.return_value = {"key": "PROJ-100"} |
| 209 | + mock_create.return_value = mock_jira |
| 210 | + |
| 211 | + args = Namespace( |
| 212 | + project="PROJ", summary="Bug", type="Bug", |
| 213 | + description=None, description_file=None, |
| 214 | + priority="High", assignee="jdoe", |
| 215 | + ) |
| 216 | + jira_create(args) |
| 217 | + |
| 218 | + fields = mock_jira.issue_create.call_args[1]["fields"] |
| 219 | + assert fields["priority"] == {"name": "High"} |
| 220 | + assert fields["assignee"] == {"name": "jdoe"} |
| 221 | + assert "description" not in fields |
| 222 | + |
| 223 | + @patch("atlassian_local_cli.jira_commands.get_config") |
| 224 | + @patch("atlassian_local_cli.jira_commands.create_jira") |
| 225 | + def test_description_from_file(self, mock_create, mock_config, tmp_path): |
| 226 | + mock_config.return_value = MagicMock(jira_url="https://jira.test.com/") |
| 227 | + mock_jira = MagicMock() |
| 228 | + mock_jira.issue_create.return_value = {"key": "PROJ-101"} |
| 229 | + mock_create.return_value = mock_jira |
| 230 | + |
| 231 | + desc_file = tmp_path / "desc.md" |
| 232 | + desc_file.write_text("Line 1\n\nLine 2\n\n- bullet\n- items") |
| 233 | + |
| 234 | + args = Namespace( |
| 235 | + project="PROJ", summary="From file", type="Task", |
| 236 | + description=None, description_file=str(desc_file), |
| 237 | + priority=None, assignee=None, |
| 238 | + ) |
| 239 | + jira_create(args) |
| 240 | + |
| 241 | + fields = mock_jira.issue_create.call_args[1]["fields"] |
| 242 | + assert "Line 1" in fields["description"] |
| 243 | + assert "Line 2" in fields["description"] |
| 244 | + assert "- bullet" in fields["description"] |
| 245 | + |
| 246 | + @patch("atlassian_local_cli.jira_commands.get_config") |
| 247 | + @patch("atlassian_local_cli.jira_commands.create_jira") |
| 248 | + def test_description_from_stdin(self, mock_create, mock_config, monkeypatch): |
| 249 | + mock_config.return_value = MagicMock(jira_url="https://jira.test.com/") |
| 250 | + mock_jira = MagicMock() |
| 251 | + mock_jira.issue_create.return_value = {"key": "PROJ-102"} |
| 252 | + mock_create.return_value = mock_jira |
| 253 | + |
| 254 | + import io |
| 255 | + monkeypatch.setattr("sys.stdin", io.StringIO("Piped\nmultiline\ncontent")) |
| 256 | + |
| 257 | + args = Namespace( |
| 258 | + project="PROJ", summary="From stdin", type="Task", |
| 259 | + description=None, description_file="-", |
| 260 | + priority=None, assignee=None, |
| 261 | + ) |
| 262 | + jira_create(args) |
| 263 | + |
| 264 | + fields = mock_jira.issue_create.call_args[1]["fields"] |
| 265 | + assert "Piped\nmultiline\ncontent" == fields["description"] |
| 266 | + |
| 267 | + def test_description_and_file_mutually_exclusive(self): |
| 268 | + args = Namespace( |
| 269 | + project="PROJ", summary="Test", type="Task", |
| 270 | + description="inline", description_file="file.md", |
| 271 | + priority=None, assignee=None, |
| 272 | + ) |
| 273 | + with pytest.raises(SystemExit): |
| 274 | + jira_create(args) |
0 commit comments