entropy-data 0.3.1__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. {entropy_data-0.3.1 → entropy_data-0.3.2}/CHANGELOG.md +4 -0
  2. {entropy_data-0.3.1 → entropy_data-0.3.2}/PKG-INFO +1 -1
  3. {entropy_data-0.3.1 → entropy_data-0.3.2}/pyproject.toml +1 -1
  4. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/client.py +53 -3
  5. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/datacontracts.py +9 -0
  6. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/dataproducts.py +9 -0
  7. entropy_data-0.3.2/src/entropy_data/commands/gitconnections.py +183 -0
  8. entropy_data-0.3.2/tests/commands/test_gitconnections.py +255 -0
  9. {entropy_data-0.3.1 → entropy_data-0.3.2}/.editorconfig +0 -0
  10. {entropy_data-0.3.1 → entropy_data-0.3.2}/.github/dependabot.yml +0 -0
  11. {entropy_data-0.3.1 → entropy_data-0.3.2}/.github/pull_request_template.md +0 -0
  12. {entropy_data-0.3.1 → entropy_data-0.3.2}/.github/workflows/ci.yaml +0 -0
  13. {entropy_data-0.3.1 → entropy_data-0.3.2}/.github/workflows/release.yaml +0 -0
  14. {entropy_data-0.3.1 → entropy_data-0.3.2}/.gitignore +0 -0
  15. {entropy_data-0.3.1 → entropy_data-0.3.2}/.pre-commit-config.yaml +0 -0
  16. {entropy_data-0.3.1 → entropy_data-0.3.2}/CLAUDE.md +0 -0
  17. {entropy_data-0.3.1 → entropy_data-0.3.2}/Dockerfile +0 -0
  18. {entropy_data-0.3.1 → entropy_data-0.3.2}/LICENSE +0 -0
  19. {entropy_data-0.3.1 → entropy_data-0.3.2}/README.md +0 -0
  20. {entropy_data-0.3.1 → entropy_data-0.3.2}/release +0 -0
  21. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/__init__.py +0 -0
  22. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/__main__.py +0 -0
  23. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/cli.py +0 -0
  24. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/__init__.py +0 -0
  25. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/access.py +0 -0
  26. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/api_keys.py +0 -0
  27. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/assets.py +0 -0
  28. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/certifications.py +0 -0
  29. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/connection.py +0 -0
  30. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/costs.py +0 -0
  31. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/definitions.py +0 -0
  32. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/events.py +0 -0
  33. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/example_data.py +0 -0
  34. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/import_export.py +0 -0
  35. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/lineage.py +0 -0
  36. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/search.py +0 -0
  37. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/settings.py +0 -0
  38. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/sourcesystems.py +0 -0
  39. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/tags.py +0 -0
  40. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/teams.py +0 -0
  41. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/test_results.py +0 -0
  42. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/commands/usage.py +0 -0
  43. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/config.py +0 -0
  44. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/output.py +0 -0
  45. {entropy_data-0.3.1 → entropy_data-0.3.2}/src/entropy_data/util.py +0 -0
  46. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/__init__.py +0 -0
  47. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/__init__.py +0 -0
  48. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_api_keys.py +0 -0
  49. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_assets.py +0 -0
  50. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_connection.py +0 -0
  51. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_costs.py +0 -0
  52. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_lineage.py +0 -0
  53. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_settings.py +0 -0
  54. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_tags.py +0 -0
  55. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_teams.py +0 -0
  56. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/commands/test_usage.py +0 -0
  57. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/conftest.py +0 -0
  58. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/test_client.py +0 -0
  59. {entropy_data-0.3.1 → entropy_data-0.3.2}/tests/test_config.py +0 -0
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.2]
4
+
5
+ - Add `git-connection` subcommands to `dataproducts` and `datacontracts`
6
+
3
7
  ## [0.3.1]
4
8
 
5
9
  - Support Python 3.11 (lowered minimum from 3.12)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entropy-data
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: CLI for Entropy Data
5
5
  Project-URL: Homepage, https://entropy-data.com
6
6
  Project-URL: Documentation, https://docs.entropy-data.com
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "entropy-data"
3
- version = "0.3.1"
3
+ version = "0.3.2"
4
4
  description = "CLI for Entropy Data"
5
5
  requires-python = ">=3.11"
6
6
  license = "MIT"
@@ -121,12 +121,15 @@ class EntropyDataClient:
121
121
  _raise_for_status(response)
122
122
  return response.headers.get(RESPONSE_HEADER_LOCATION_HTML)
123
123
 
124
- def post_action_json(self, path: str, resource_id: str, action: str, params: dict | None = None,
125
- timeout: int = REQUEST_TIMEOUT) -> dict:
124
+ def post_action_json(
125
+ self, path: str, resource_id: str, action: str, params: dict | None = None, timeout: int = REQUEST_TIMEOUT
126
+ ) -> dict:
126
127
  """POST /api/{path}/{id}/{action} with query params. Returns response JSON."""
127
128
  _validate_resource_id(resource_id)
128
129
  response = self.session.post(
129
- f"{self.base_url}/api/{path}/{resource_id}/{action}", params=params, timeout=timeout,
130
+ f"{self.base_url}/api/{path}/{resource_id}/{action}",
131
+ params=params,
132
+ timeout=timeout,
130
133
  )
131
134
  _raise_for_status(response)
132
135
  return response.json()
@@ -155,6 +158,53 @@ class EntropyDataClient:
155
158
  _raise_for_status(response)
156
159
  return response.json()
157
160
 
161
+ def get_gitconnection(self, path: str, resource_id: str) -> dict:
162
+ """GET /api/{path}/{id}/gitconnection."""
163
+ _validate_resource_id(resource_id)
164
+ response = self.session.get(
165
+ f"{self.base_url}/api/{path}/{resource_id}/gitconnection",
166
+ timeout=REQUEST_TIMEOUT,
167
+ )
168
+ _raise_for_status(response)
169
+ return response.json()
170
+
171
+ def put_gitconnection(self, path: str, resource_id: str, body: dict) -> dict:
172
+ """PUT /api/{path}/{id}/gitconnection."""
173
+ _validate_resource_id(resource_id)
174
+ response = self.session.put(
175
+ f"{self.base_url}/api/{path}/{resource_id}/gitconnection",
176
+ json=body,
177
+ timeout=REQUEST_TIMEOUT,
178
+ )
179
+ _raise_for_status(response)
180
+ return response.json()
181
+
182
+ def delete_gitconnection(self, path: str, resource_id: str) -> None:
183
+ """DELETE /api/{path}/{id}/gitconnection."""
184
+ _validate_resource_id(resource_id)
185
+ response = self.session.delete(
186
+ f"{self.base_url}/api/{path}/{resource_id}/gitconnection",
187
+ timeout=REQUEST_TIMEOUT,
188
+ )
189
+ _raise_for_status(response)
190
+
191
+ def gitconnection_action(
192
+ self,
193
+ path: str,
194
+ resource_id: str,
195
+ action: str,
196
+ body: dict | None = None,
197
+ ) -> dict:
198
+ """POST /api/{path}/{id}/gitconnection/{action}. action ∈ {pull, push, push-pr}."""
199
+ _validate_resource_id(resource_id)
200
+ response = self.session.post(
201
+ f"{self.base_url}/api/{path}/{resource_id}/gitconnection/{action}",
202
+ json=body if body is not None else None,
203
+ timeout=REQUEST_TIMEOUT,
204
+ )
205
+ _raise_for_status(response)
206
+ return response.json()
207
+
158
208
  def search(self, query: str, **params) -> dict:
159
209
  """GET /api/search."""
160
210
  params["query"] = query
@@ -113,3 +113,12 @@ def delete_datacontract(
113
113
  print_success(f"Data contract '{id}' deleted.")
114
114
  except Exception as e:
115
115
  handle_error(e)
116
+
117
+
118
+ from entropy_data.commands.gitconnections import make_gitconnection_app # noqa: E402
119
+
120
+ datacontracts_app.add_typer(
121
+ make_gitconnection_app(RESOURCE_PATH, "Data contract"),
122
+ name="gitconnection",
123
+ help="Manage the git connection.",
124
+ )
@@ -91,3 +91,12 @@ def delete_dataproduct(
91
91
  print_success(f"Data product '{id}' deleted.")
92
92
  except Exception as e:
93
93
  handle_error(e)
94
+
95
+
96
+ from entropy_data.commands.gitconnections import make_gitconnection_app # noqa: E402
97
+
98
+ dataproducts_app.add_typer(
99
+ make_gitconnection_app(RESOURCE_PATH, "Data product"),
100
+ name="gitconnection",
101
+ help="Manage the git connection.",
102
+ )
@@ -0,0 +1,183 @@
1
+ """Git connection subcommands. Used as a sub-typer of dataproducts and datacontracts."""
2
+
3
+ import json
4
+ from typing import Annotated, Optional
5
+
6
+ import typer
7
+
8
+ from entropy_data.output import OutputFormat, print_link, print_success
9
+
10
+ GIT_CONNECTION_TYPES = ("github", "gitlab", "bitbucket", "azuredevops")
11
+
12
+
13
+ def make_gitconnection_app(resource_path: str, resource_label: str) -> typer.Typer:
14
+ """Build a Typer app exposing /api/{resource_path}/{id}/gitconnection operations.
15
+
16
+ `resource_path` is the URL segment ("dataproducts" or "datacontracts").
17
+ `resource_label` is the human-readable name shown in success messages.
18
+ """
19
+
20
+ app = typer.Typer(no_args_is_help=True)
21
+
22
+ @app.command("get")
23
+ def get_(
24
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
25
+ output: Annotated[Optional[OutputFormat], typer.Option("--output", "-o", help="Output format.")] = None,
26
+ ) -> None:
27
+ """Get the git connection."""
28
+ from entropy_data.cli import get_client, get_output_format, handle_error
29
+
30
+ fmt = output or get_output_format()
31
+ try:
32
+ client = get_client()
33
+ data = client.get_gitconnection(resource_path, id)
34
+ if fmt == OutputFormat.json:
35
+ print(json.dumps(data, indent=2))
36
+ else:
37
+ print(json.dumps(data, indent=2))
38
+ except Exception as e:
39
+ handle_error(e)
40
+
41
+ @app.command("put")
42
+ def put_(
43
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
44
+ repository_url: Annotated[str, typer.Option("--repository-url", help="URL of the Git repository.")] = ...,
45
+ repository_path: Annotated[
46
+ str, typer.Option("--repository-path", help="Path to the YAML file in the repository.")
47
+ ] = ...,
48
+ repository_branch: Annotated[
49
+ Optional[str],
50
+ typer.Option("--repository-branch", help="Branch to use. Defaults to 'main'."),
51
+ ] = None,
52
+ git_connection_type: Annotated[
53
+ Optional[str],
54
+ typer.Option(
55
+ "--git-connection-type",
56
+ help=f"Git provider type. One of: {', '.join(GIT_CONNECTION_TYPES)}.",
57
+ ),
58
+ ] = None,
59
+ host: Annotated[
60
+ Optional[str],
61
+ typer.Option("--host", help="Host of a self-hosted git provider. Omit for SaaS."),
62
+ ] = None,
63
+ git_credential_external_id: Annotated[
64
+ Optional[str],
65
+ typer.Option(
66
+ "--git-credential-external-id",
67
+ help="External ID of a stored git credential to use.",
68
+ ),
69
+ ] = None,
70
+ ) -> None:
71
+ """Create or update the git connection."""
72
+ from entropy_data.cli import get_client, handle_error
73
+
74
+ if git_connection_type and git_connection_type not in GIT_CONNECTION_TYPES:
75
+ raise typer.BadParameter(
76
+ f"Must be one of: {', '.join(GIT_CONNECTION_TYPES)}",
77
+ param_hint="--git-connection-type",
78
+ )
79
+ if not git_connection_type and not git_credential_external_id:
80
+ raise typer.BadParameter(
81
+ "At least one of --git-connection-type or --git-credential-external-id must be provided.",
82
+ )
83
+
84
+ body: dict = {"repositoryUrl": repository_url, "repositoryPath": repository_path}
85
+ if repository_branch:
86
+ body["repositoryBranch"] = repository_branch
87
+ if git_connection_type:
88
+ body["gitConnectionType"] = git_connection_type
89
+ if host:
90
+ body["host"] = host
91
+ if git_credential_external_id:
92
+ body["gitCredentialExternalId"] = git_credential_external_id
93
+
94
+ try:
95
+ client = get_client()
96
+ data = client.put_gitconnection(resource_path, id, body)
97
+ print_success(f"Git connection saved for {resource_label.lower()} '{id}'.")
98
+ print_link(data.get("webLink"))
99
+ except Exception as e:
100
+ handle_error(e)
101
+
102
+ @app.command("delete")
103
+ def delete_(
104
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
105
+ ) -> None:
106
+ """Delete the git connection."""
107
+ from entropy_data.cli import get_client, handle_error
108
+
109
+ try:
110
+ client = get_client()
111
+ client.delete_gitconnection(resource_path, id)
112
+ print_success(f"Git connection deleted for {resource_label.lower()} '{id}'.")
113
+ except Exception as e:
114
+ handle_error(e)
115
+
116
+ @app.command("pull")
117
+ def pull_(
118
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
119
+ ) -> None:
120
+ """Pull the file from Git into Entropy Data."""
121
+ from entropy_data.cli import get_client, handle_error
122
+
123
+ try:
124
+ client = get_client()
125
+ data = client.gitconnection_action(resource_path, id, "pull")
126
+ print_success(f"{resource_label} '{id}' pulled from Git.")
127
+ print_link(data.get("webLink"))
128
+ except Exception as e:
129
+ handle_error(e)
130
+
131
+ @app.command("push")
132
+ def push_(
133
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
134
+ commit_message: Annotated[
135
+ Optional[str], typer.Option("--commit-message", help="Custom commit message.")
136
+ ] = None,
137
+ ) -> None:
138
+ """Push the current Entropy Data file to Git."""
139
+ from entropy_data.cli import get_client, handle_error
140
+
141
+ body: dict | None = {"commitMessage": commit_message} if commit_message else None
142
+ try:
143
+ client = get_client()
144
+ data = client.gitconnection_action(resource_path, id, "push", body)
145
+ print_success(f"{resource_label} '{id}' pushed to Git.")
146
+ print_link(data.get("webLink"))
147
+ except Exception as e:
148
+ handle_error(e)
149
+
150
+ @app.command("push-pr")
151
+ def push_pr(
152
+ id: Annotated[str, typer.Argument(help=f"{resource_label} ID.")],
153
+ commit_message: Annotated[
154
+ Optional[str], typer.Option("--commit-message", help="Custom commit message.")
155
+ ] = None,
156
+ branch_name: Annotated[Optional[str], typer.Option("--branch-name", help="Name of the new branch.")] = None,
157
+ title: Annotated[Optional[str], typer.Option("--title", help="Pull request title.")] = None,
158
+ comment: Annotated[
159
+ Optional[str],
160
+ typer.Option("--comment", help="Pull request description / comment."),
161
+ ] = None,
162
+ ) -> None:
163
+ """Push the current Entropy Data file to Git as a pull/merge request."""
164
+ from entropy_data.cli import get_client, handle_error
165
+
166
+ body: dict = {}
167
+ if commit_message:
168
+ body["commitMessage"] = commit_message
169
+ if branch_name:
170
+ body["branchName"] = branch_name
171
+ if title:
172
+ body["title"] = title
173
+ if comment:
174
+ body["comment"] = comment
175
+ try:
176
+ client = get_client()
177
+ data = client.gitconnection_action(resource_path, id, "push-pr", body or None)
178
+ print_success(f"{resource_label} '{id}' pushed to Git as pull request.")
179
+ print_link(data.get("webLink"))
180
+ except Exception as e:
181
+ handle_error(e)
182
+
183
+ return app
@@ -0,0 +1,255 @@
1
+ """Tests for git connection subcommands on dataproducts and datacontracts."""
2
+
3
+ import json
4
+
5
+ import pytest
6
+ import responses
7
+ from typer.testing import CliRunner
8
+
9
+ import entropy_data.config as cfg
10
+ from entropy_data.cli import app
11
+
12
+ runner = CliRunner()
13
+ BASE_URL = "https://api.entropy-data.com"
14
+
15
+
16
+ CONNECTION_RESPONSE = {
17
+ "gitConnectionId": "11111111-1111-1111-1111-111111111111",
18
+ "gitConnectionType": "github",
19
+ "repositoryUrl": "https://github.com/acme/contracts",
20
+ "repositoryBranch": "main",
21
+ "repositoryPath": "contracts/orders.yaml",
22
+ "syncStatus": "UP_TO_DATE",
23
+ "webLink": "https://github.com/acme/contracts/blob/main/contracts/orders.yaml",
24
+ "lastHash": "abc123",
25
+ }
26
+
27
+
28
+ @pytest.fixture
29
+ def configured(monkeypatch, tmp_path):
30
+ monkeypatch.setattr(cfg, "CONFIG_FILE", tmp_path / "config.toml")
31
+ monkeypatch.setenv("ENTROPY_DATA_API_KEY", "test-key")
32
+
33
+
34
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
35
+ @responses.activate
36
+ def test_gitconnection_get(configured, resource):
37
+ responses.add(
38
+ responses.GET,
39
+ f"{BASE_URL}/api/{resource}/orders/gitconnection",
40
+ json=CONNECTION_RESPONSE,
41
+ status=200,
42
+ )
43
+ result = runner.invoke(app, [resource, "gitconnection", "get", "orders"])
44
+ assert result.exit_code == 0
45
+ assert "github.com/acme/contracts" in result.output
46
+
47
+
48
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
49
+ @responses.activate
50
+ def test_gitconnection_put(configured, resource):
51
+ responses.add(
52
+ responses.PUT,
53
+ f"{BASE_URL}/api/{resource}/orders/gitconnection",
54
+ json=CONNECTION_RESPONSE,
55
+ status=200,
56
+ )
57
+ result = runner.invoke(
58
+ app,
59
+ [
60
+ resource,
61
+ "gitconnection",
62
+ "put",
63
+ "orders",
64
+ "--repository-url",
65
+ "https://github.com/acme/contracts",
66
+ "--repository-path",
67
+ "contracts/orders.yaml",
68
+ "--git-connection-type",
69
+ "github",
70
+ ],
71
+ )
72
+ assert result.exit_code == 0
73
+ assert "saved" in result.output
74
+ sent = json.loads(responses.calls[-1].request.body)
75
+ assert sent["repositoryUrl"] == "https://github.com/acme/contracts"
76
+ assert sent["repositoryPath"] == "contracts/orders.yaml"
77
+ assert sent["gitConnectionType"] == "github"
78
+
79
+
80
+ def test_gitconnection_put_requires_credential_or_type(configured):
81
+ result = runner.invoke(
82
+ app,
83
+ [
84
+ "dataproducts",
85
+ "gitconnection",
86
+ "put",
87
+ "orders",
88
+ "--repository-url",
89
+ "https://github.com/acme/contracts",
90
+ "--repository-path",
91
+ "contracts/orders.yaml",
92
+ ],
93
+ )
94
+ assert result.exit_code != 0
95
+
96
+
97
+ def test_gitconnection_put_rejects_invalid_type(configured):
98
+ result = runner.invoke(
99
+ app,
100
+ [
101
+ "dataproducts",
102
+ "gitconnection",
103
+ "put",
104
+ "orders",
105
+ "--repository-url",
106
+ "https://github.com/acme/contracts",
107
+ "--repository-path",
108
+ "contracts/orders.yaml",
109
+ "--git-connection-type",
110
+ "svn",
111
+ ],
112
+ )
113
+ assert result.exit_code != 0
114
+
115
+
116
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
117
+ @responses.activate
118
+ def test_gitconnection_put_with_credential_external_id(configured, resource):
119
+ responses.add(
120
+ responses.PUT,
121
+ f"{BASE_URL}/api/{resource}/orders/gitconnection",
122
+ json=CONNECTION_RESPONSE,
123
+ status=200,
124
+ )
125
+ result = runner.invoke(
126
+ app,
127
+ [
128
+ resource,
129
+ "gitconnection",
130
+ "put",
131
+ "orders",
132
+ "--repository-url",
133
+ "https://github.com/acme/contracts",
134
+ "--repository-path",
135
+ "contracts/orders.yaml",
136
+ "--git-credential-external-id",
137
+ "acme-ci",
138
+ ],
139
+ )
140
+ assert result.exit_code == 0
141
+ sent = json.loads(responses.calls[-1].request.body)
142
+ assert sent["gitCredentialExternalId"] == "acme-ci"
143
+ assert "gitConnectionType" not in sent
144
+
145
+
146
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
147
+ @responses.activate
148
+ def test_gitconnection_delete(configured, resource):
149
+ responses.add(
150
+ responses.DELETE,
151
+ f"{BASE_URL}/api/{resource}/orders/gitconnection",
152
+ status=200,
153
+ )
154
+ result = runner.invoke(app, [resource, "gitconnection", "delete", "orders"])
155
+ assert result.exit_code == 0
156
+ assert "deleted" in result.output
157
+
158
+
159
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
160
+ @responses.activate
161
+ def test_gitconnection_pull(configured, resource):
162
+ responses.add(
163
+ responses.POST,
164
+ f"{BASE_URL}/api/{resource}/orders/gitconnection/pull",
165
+ json=CONNECTION_RESPONSE,
166
+ status=200,
167
+ )
168
+ result = runner.invoke(app, [resource, "gitconnection", "pull", "orders"])
169
+ assert result.exit_code == 0
170
+ assert "pulled" in result.output
171
+
172
+
173
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
174
+ @responses.activate
175
+ def test_gitconnection_push(configured, resource):
176
+ responses.add(
177
+ responses.POST,
178
+ f"{BASE_URL}/api/{resource}/orders/gitconnection/push",
179
+ json=CONNECTION_RESPONSE,
180
+ status=200,
181
+ )
182
+ result = runner.invoke(
183
+ app,
184
+ [resource, "gitconnection", "push", "orders", "--commit-message", "update orders"],
185
+ )
186
+ assert result.exit_code == 0
187
+ assert "pushed" in result.output
188
+ sent = json.loads(responses.calls[-1].request.body)
189
+ assert sent["commitMessage"] == "update orders"
190
+
191
+
192
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
193
+ @responses.activate
194
+ def test_gitconnection_push_no_body(configured, resource):
195
+ responses.add(
196
+ responses.POST,
197
+ f"{BASE_URL}/api/{resource}/orders/gitconnection/push",
198
+ json=CONNECTION_RESPONSE,
199
+ status=200,
200
+ )
201
+ result = runner.invoke(app, [resource, "gitconnection", "push", "orders"])
202
+ assert result.exit_code == 0
203
+ assert responses.calls[-1].request.body in (None, b"null", "null")
204
+
205
+
206
+ @pytest.mark.parametrize("resource", ["dataproducts", "datacontracts"])
207
+ @responses.activate
208
+ def test_gitconnection_push_pr(configured, resource):
209
+ responses.add(
210
+ responses.POST,
211
+ f"{BASE_URL}/api/{resource}/orders/gitconnection/push-pr",
212
+ json=CONNECTION_RESPONSE,
213
+ status=200,
214
+ )
215
+ result = runner.invoke(
216
+ app,
217
+ [
218
+ resource,
219
+ "gitconnection",
220
+ "push-pr",
221
+ "orders",
222
+ "--branch-name",
223
+ "feat/orders",
224
+ "--title",
225
+ "Update orders",
226
+ "--commit-message",
227
+ "update orders",
228
+ "--comment",
229
+ "ci push",
230
+ ],
231
+ )
232
+ assert result.exit_code == 0
233
+ sent = json.loads(responses.calls[-1].request.body)
234
+ assert sent["branchName"] == "feat/orders"
235
+ assert sent["title"] == "Update orders"
236
+ assert sent["commitMessage"] == "update orders"
237
+ assert sent["comment"] == "ci push"
238
+
239
+
240
+ def test_gitconnection_help_under_dataproducts():
241
+ result = runner.invoke(app, ["dataproducts", "gitconnection", "--help"])
242
+ assert result.exit_code == 0
243
+ assert "get" in result.output
244
+ assert "put" in result.output
245
+ assert "delete" in result.output
246
+ assert "pull" in result.output
247
+ assert "push" in result.output
248
+ assert "push-pr" in result.output
249
+
250
+
251
+ def test_gitconnection_help_under_datacontracts():
252
+ result = runner.invoke(app, ["datacontracts", "gitconnection", "--help"])
253
+ assert result.exit_code == 0
254
+ assert "get" in result.output
255
+ assert "push-pr" in result.output
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes