scriptengine-tasks-ecearth 0.7.0__tar.gz → 0.8.0__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 (63) hide show
  1. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/PKG-INFO +4 -2
  2. scriptengine_tasks_ecearth-0.8.0/monitoring/gitlab.py +140 -0
  3. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/si3_hemis_sum_month_mean_timeseries.py +6 -3
  4. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/pyproject.toml +3 -1
  5. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/PKG-INFO +4 -2
  6. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/SOURCES.txt +2 -0
  7. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/entry_points.txt +1 -0
  8. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/requires.txt +1 -0
  9. scriptengine_tasks_ecearth-0.8.0/tests/test_gitlab.py +112 -0
  10. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/LICENSE +0 -0
  11. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/README.md +0 -0
  12. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/__init__.py +0 -0
  13. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/cubes.py +0 -0
  14. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/dates.py +0 -0
  15. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/exceptions.py +0 -0
  16. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/files.py +0 -0
  17. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/map_type_handling.py +0 -0
  18. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/nemo.py +0 -0
  19. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/helpers/presentation_objects.py +0 -0
  20. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/diskusage_rte_scalar.py +0 -0
  21. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/linear_combination.py +0 -0
  22. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/map.py +0 -0
  23. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/markdown.py +0 -0
  24. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/nemo_all_mean_map.py +0 -0
  25. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/nemo_time_mean_temporalmap.py +0 -0
  26. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/nemo_timeseries.py +0 -0
  27. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/oifs_all_mean_map.py +0 -0
  28. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/oifs_global_mean_year_mean_timeseries.py +0 -0
  29. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/oifs_year_mean_temporalmap.py +0 -0
  30. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/redmine.py +0 -0
  31. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/scalar.py +0 -0
  32. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/si3_hemis_point_month_mean_all_mean_map.py +0 -0
  33. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/si3_hemis_point_month_mean_temporalmap.py +0 -0
  34. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/simulatedyears_rte_scalar.py +0 -0
  35. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/temporalmap.py +0 -0
  36. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/monitoring/timeseries.py +0 -0
  37. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/dependency_links.txt +0 -0
  38. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/scriptengine_tasks_ecearth.egg-info/top_level.txt +0 -0
  39. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/setup.cfg +0 -0
  40. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/setup.py +0 -0
  41. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_cubes.py +0 -0
  42. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_dates.py +0 -0
  43. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_diskusage_rte_scalar.py +0 -0
  44. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_file_handling.py +0 -0
  45. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_linear_combination.py +0 -0
  46. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_map.py +0 -0
  47. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_map_type_handling.py +0 -0
  48. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_markdown.py +0 -0
  49. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_nemo_all_mean_map.py +0 -0
  50. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_nemo_time_mean_temporalmap.py +0 -0
  51. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_nemo_timeseries.py +0 -0
  52. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_oifs_all_mean_map.py +0 -0
  53. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_oifs_global_mean_year_mean_timeseries.py +0 -0
  54. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_oifs_year_mean_temporalmap.py +0 -0
  55. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_presentation_objects.py +0 -0
  56. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_redmine.py +0 -0
  57. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_scalar.py +0 -0
  58. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_si3_hemis_point_month_mean_all_mean_map.py +0 -0
  59. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_si3_hemis_point_month_mean_temporalmap.py +0 -0
  60. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_si3_hemis_sum_month_mean_timeseries.py +0 -0
  61. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_simulatedyears_rte_scalar.py +0 -0
  62. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_temporalmap.py +0 -0
  63. {scriptengine_tasks_ecearth-0.7.0 → scriptengine_tasks_ecearth-0.8.0}/tests/test_timeseries.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: scriptengine-tasks-ecearth
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: ScriptEngine tasks for use with the EC-Earth climate model
5
5
  Author-email: Valentina Schueller <valentina.schueller@gmail.com>, Uwe Fladrich <uwe.fladrich@protonmail.com>
6
6
  Project-URL: Homepage, https://github.com/uwefladrich/scriptengine-tasks-ecearth
@@ -19,6 +19,8 @@ Requires-Dist: imageio>=2.18
19
19
  Requires-Dist: scitools-iris>=3.5
20
20
  Requires-Dist: cartopy>=0.20
21
21
  Requires-Dist: python-redmine
22
+ Requires-Dist: python-gitlab
23
+ Dynamic: license-file
22
24
 
23
25
  [![Tests](https://github.com/uwefladrich/scriptengine-tasks-ecearth/actions/workflows/pytest.yml/badge.svg)](https://github.com/uwefladrich/scriptengine-tasks-ecearth/actions)
24
26
  [![Coverage Status](https://coveralls.io/repos/github/uwefladrich/scriptengine-tasks-ecearth/badge.svg)](https://coveralls.io/github/uwefladrich/scriptengine-tasks-ecearth)
@@ -0,0 +1,140 @@
1
+ """Presentation Task that uploads Data and Plots to the EC-Earth 4 Gitlab."""
2
+
3
+ import re
4
+ import urllib.parse
5
+ from pathlib import Path
6
+
7
+ import gitlab
8
+ import jinja2
9
+ import requests.exceptions
10
+ from scriptengine.exceptions import ScriptEngineTaskRunError
11
+ from scriptengine.jinja import filters as j2filters
12
+ from scriptengine.tasks.core import Task, timed_runner
13
+
14
+ from helpers.exceptions import PresentationException
15
+ from helpers.presentation_objects import PresentationObject
16
+
17
+ # Repository where monitoring results are posted
18
+ SERVER_URL = "https://git.smhi.se"
19
+ PROJECT_ID = 1982
20
+
21
+
22
+ class Gitlab(Task):
23
+ """Gitlab Presentation Task"""
24
+
25
+ _required_arguments = (
26
+ "src",
27
+ "local_dst",
28
+ "subject",
29
+ "template",
30
+ "api_key",
31
+ )
32
+
33
+ def __init__(self, arguments=None):
34
+ Gitlab.check_arguments(arguments)
35
+ super().__init__(arguments)
36
+
37
+ @timed_runner
38
+ def run(self, context):
39
+ sources = self.getarg("src", context)
40
+ dst_folder = self.getarg("local_dst", context)
41
+ issue_subject = self.getarg("subject", context, parse_yaml=False)
42
+ template_path = self.getarg("template", context)
43
+ key = self.getarg("api_key", context)
44
+ self.log_info(f"Create Gitlab issue '{issue_subject}'.")
45
+ self.log_debug(f"Template: {template_path}, Source File(s): {sources}")
46
+
47
+ presentation_list = self.get_presentation_list(sources, dst_folder)
48
+ gitlab_template = self.get_template(context, template_path)
49
+ gitlab_template.globals["urlencode"] = urllib.parse.quote
50
+
51
+ self.log_debug("Connecting to Gitlab.")
52
+ project, issue = self.get_project_and_issue(key, issue_subject)
53
+
54
+ self.log_debug("Uploading attachments.")
55
+ issue.uploads = []
56
+ for item in presentation_list:
57
+ if item["presentation_type"] == "image":
58
+ file_name = Path(item["path"]).name
59
+ upload = project.upload(file_name, filepath=f"{dst_folder}/{file_name}")
60
+ item["image_link"] = upload[
61
+ "markdown"
62
+ ] # string of the form "![]()" generated by Gitlab
63
+
64
+ # render the template and add as description
65
+ self.log_debug("Updating the issue description.")
66
+ issue.description = gitlab_template.render(
67
+ presentation_list=presentation_list,
68
+ issue_url=issue.web_url,
69
+ create_anchor=create_anchor,
70
+ )
71
+ self.log_debug("Saving issue.")
72
+ issue.save()
73
+
74
+ def get_presentation_list(self, sources, dst_folder):
75
+ """create a list of presentation objects"""
76
+ self.log_debug("Getting list of presentation objects.")
77
+ presentation_list = []
78
+ for src in sources:
79
+ try:
80
+ try:
81
+ pres_object = PresentationObject(dst_folder, **src)
82
+ except TypeError:
83
+ pres_object = PresentationObject(dst_folder, src)
84
+ self.log_debug(
85
+ f"Loading {pres_object.loader.diag_type} diagnostic from {pres_object.loader.path}."
86
+ )
87
+ presentation_list.append(pres_object.create_dict())
88
+ except PresentationException as msg:
89
+ self.log_warning(f"Can not present diagnostic: {msg}")
90
+ return presentation_list
91
+
92
+ def get_template(self, context, template):
93
+ """get Jinja2 template file"""
94
+ search_path = [".", "templates"]
95
+ if "_se_cmd_cwd" in context:
96
+ search_path.extend(
97
+ [
98
+ context["_se_cmd_cwd"],
99
+ Path(context["_se_cmd_cwd"]) / "templates",
100
+ ]
101
+ )
102
+ self.log_debug(f"Search path for template: {search_path}")
103
+
104
+ loader = jinja2.FileSystemLoader(search_path)
105
+ environment = jinja2.Environment(loader=loader)
106
+ for name, function in j2filters().items():
107
+ environment.filters[name] = function
108
+ return environment.get_template(template)
109
+
110
+ def get_project_and_issue(self, key, issue_subject):
111
+ """Connect to Gitlab server, find and return correct issue and project based on user input"""
112
+
113
+ gl = gitlab.Gitlab(SERVER_URL, private_token=key)
114
+ try:
115
+ project = gl.projects.get(PROJECT_ID)
116
+ except (
117
+ gitlab.GitlabAuthenticationError,
118
+ requests.exceptions.ConnectionError,
119
+ ) as e:
120
+ msg = f"Could not log in to Gitlab server ({e})"
121
+ self.log_error(msg)
122
+ raise ScriptEngineTaskRunError()
123
+
124
+ # Find issue or create if none exists
125
+ issues = project.issues.list()
126
+ issue = next((issue for issue in issues if issue.title == issue_subject), None)
127
+ if issue is None:
128
+ issue = project.issues.create({"title": issue_subject})
129
+ issue.save()
130
+ return project, issue
131
+
132
+
133
+ def create_anchor(title: str) -> str:
134
+ """
135
+ create correct anchors for Gitlab issue URLs
136
+ """
137
+ anchor = re.sub(r"[^a-zA-Z\s-]", "", title)
138
+ anchor = re.sub(r"\s+(\-+\s*)?", "-", anchor)
139
+ anchor = anchor.lower()
140
+ return anchor
@@ -1,6 +1,5 @@
1
1
  """Processing Task that calculates the seasonal cycle of sea ice variables in one leg."""
2
2
 
3
- import warnings
4
3
  from pathlib import Path
5
4
 
6
5
  import cf_units
@@ -19,12 +18,14 @@ _meta_dict = {
19
18
  "standard_name": "sea_ice_volume",
20
19
  "var_name": "sivol",
21
20
  "new_unit": "1e3 km3",
21
+ "old_unit": "m3",
22
22
  },
23
23
  "siconc": {
24
24
  "long_name": "Sea-Ice Area",
25
25
  "standard_name": "sea_ice_area",
26
26
  "var_name": "siarea",
27
27
  "new_unit": "1e6 km2",
28
+ "old_unit": "m2",
28
29
  },
29
30
  }
30
31
 
@@ -75,7 +76,7 @@ class Si3HemisSumMonthMeanTimeseries(Timeseries):
75
76
  self.log_warning(
76
77
  (
77
78
  f"Invalid varname '{varname}', must be one of {_meta_dict.keys()}; "
78
- "diagnostic will not be ignored."
79
+ "diagnostic will be ignored."
79
80
  )
80
81
  )
81
82
  return
@@ -84,7 +85,7 @@ class Si3HemisSumMonthMeanTimeseries(Timeseries):
84
85
  self.log_warning(
85
86
  (
86
87
  f"Invalid hemisphere '{hemisphere}', must be 'north' or 'south'; "
87
- "diagnostic will not be ignored."
88
+ "diagnostic will be ignored."
88
89
  )
89
90
  )
90
91
  return
@@ -100,6 +101,8 @@ class Si3HemisSumMonthMeanTimeseries(Timeseries):
100
101
  this_leg, domain, "T", iris.analysis.SUM
101
102
  )
102
103
 
104
+ # sivolu and siarea do not have units assigned, we need to add them manually
105
+ this_leg_summed.units = cf_units.Unit(_meta_dict[varname]["old_unit"])
103
106
  this_leg_summed.standard_name = _meta_dict[varname]["standard_name"]
104
107
  this_leg_summed.convert_units(_meta_dict[varname]["new_unit"])
105
108
  this_leg_summed.long_name = (
@@ -7,7 +7,7 @@
7
7
 
8
8
  [project]
9
9
  name = "scriptengine-tasks-ecearth"
10
- version = "0.7.0"
10
+ version = "0.8.0"
11
11
  authors = [
12
12
  { name = "Valentina Schueller", email = "valentina.schueller@gmail.com" },
13
13
  { name = "Uwe Fladrich", email = "uwe.fladrich@protonmail.com" },
@@ -29,6 +29,7 @@
29
29
  "scitools-iris>=3.5",
30
30
  "cartopy>=0.20",
31
31
  "python-redmine",
32
+ "python-gitlab",
32
33
  ]
33
34
 
34
35
  [project.urls]
@@ -54,4 +55,5 @@
54
55
  "ece.mon.oifs_global_mean_year_mean_timeseries" = "monitoring.oifs_global_mean_year_mean_timeseries:OifsGlobalMeanYearMeanTimeseries"
55
56
  "ece.mon.presentation.markdown" = "monitoring.markdown:Markdown"
56
57
  "ece.mon.presentation.redmine" = "monitoring.redmine:Redmine"
58
+ "ece.mon.presentation.gitlab" = "monitoring.gitlab:Gitlab"
57
59
  "ece.mon.linear_combination" = "monitoring.linear_combination:LinearCombination"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: scriptengine-tasks-ecearth
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: ScriptEngine tasks for use with the EC-Earth climate model
5
5
  Author-email: Valentina Schueller <valentina.schueller@gmail.com>, Uwe Fladrich <uwe.fladrich@protonmail.com>
6
6
  Project-URL: Homepage, https://github.com/uwefladrich/scriptengine-tasks-ecearth
@@ -19,6 +19,8 @@ Requires-Dist: imageio>=2.18
19
19
  Requires-Dist: scitools-iris>=3.5
20
20
  Requires-Dist: cartopy>=0.20
21
21
  Requires-Dist: python-redmine
22
+ Requires-Dist: python-gitlab
23
+ Dynamic: license-file
22
24
 
23
25
  [![Tests](https://github.com/uwefladrich/scriptengine-tasks-ecearth/actions/workflows/pytest.yml/badge.svg)](https://github.com/uwefladrich/scriptengine-tasks-ecearth/actions)
24
26
  [![Coverage Status](https://coveralls.io/repos/github/uwefladrich/scriptengine-tasks-ecearth/badge.svg)](https://coveralls.io/github/uwefladrich/scriptengine-tasks-ecearth)
@@ -11,6 +11,7 @@ helpers/map_type_handling.py
11
11
  helpers/nemo.py
12
12
  helpers/presentation_objects.py
13
13
  monitoring/diskusage_rte_scalar.py
14
+ monitoring/gitlab.py
14
15
  monitoring/linear_combination.py
15
16
  monitoring/map.py
16
17
  monitoring/markdown.py
@@ -38,6 +39,7 @@ tests/test_cubes.py
38
39
  tests/test_dates.py
39
40
  tests/test_diskusage_rte_scalar.py
40
41
  tests/test_file_handling.py
42
+ tests/test_gitlab.py
41
43
  tests/test_linear_combination.py
42
44
  tests/test_map.py
43
45
  tests/test_map_type_handling.py
@@ -10,6 +10,7 @@ ece.mon.nemo_year_mean_timeseries = monitoring.nemo_timeseries:NemoYearMeanTimes
10
10
  ece.mon.oifs_all_mean_map = monitoring.oifs_all_mean_map:OifsAllMeanMap
11
11
  ece.mon.oifs_global_mean_year_mean_timeseries = monitoring.oifs_global_mean_year_mean_timeseries:OifsGlobalMeanYearMeanTimeseries
12
12
  ece.mon.oifs_year_mean_temporalmap = monitoring.oifs_year_mean_temporalmap:OifsYearMeanTemporalmap
13
+ ece.mon.presentation.gitlab = monitoring.gitlab:Gitlab
13
14
  ece.mon.presentation.markdown = monitoring.markdown:Markdown
14
15
  ece.mon.presentation.redmine = monitoring.redmine:Redmine
15
16
  ece.mon.scalar = monitoring.scalar:Scalar
@@ -6,3 +6,4 @@ imageio>=2.18
6
6
  scitools-iris>=3.5
7
7
  cartopy>=0.20
8
8
  python-redmine
9
+ python-gitlab
@@ -0,0 +1,112 @@
1
+ """Tests for monitoring/gitlab.py"""
2
+
3
+ from unittest.mock import Mock, patch
4
+
5
+ import gitlab
6
+ import jinja2.exceptions
7
+ import pytest
8
+ import scriptengine.exceptions
9
+
10
+ from monitoring.gitlab import Gitlab, create_anchor
11
+
12
+
13
+ def test_gitlab_presentation_list(tmp_path):
14
+ init = {
15
+ "src": str(tmp_path),
16
+ "local_dst": str(tmp_path),
17
+ "template": str(tmp_path / "gitlab.txt.j2"),
18
+ "subject": "Test Issue",
19
+ "api_key": "Invalid Key",
20
+ }
21
+ redmine_task = Gitlab(init)
22
+ test_sources = ["path.txt", {"path": "path.txt"}, "path.yml"]
23
+ with patch.object(redmine_task, "log_warning") as mock:
24
+ result = redmine_task.get_presentation_list(test_sources, str(tmp_path))
25
+ mock.assert_called_with("Can not present diagnostic: File not found: path.yml")
26
+ assert result == []
27
+
28
+
29
+ def test_gitlab_connection_error(tmp_path):
30
+ init = {
31
+ "src": str(tmp_path),
32
+ "local_dst": str(tmp_path),
33
+ "template": str(tmp_path / "gitlab.txt.j2"),
34
+ "subject": "Test Issue",
35
+ "api_key": "Invalid Key",
36
+ }
37
+ gitlab_task = Gitlab(init)
38
+ pytest.raises(
39
+ scriptengine.exceptions.ScriptEngineTaskRunError,
40
+ gitlab_task.get_project_and_issue,
41
+ init["api_key"],
42
+ init["subject"],
43
+ )
44
+
45
+
46
+ def test_gitlab_auth_error(tmp_path):
47
+ init = {
48
+ "src": str(tmp_path),
49
+ "local_dst": str(tmp_path),
50
+ "template": str(tmp_path / "gitlab.txt.j2"),
51
+ "subject": "Test Issue",
52
+ "api_key": "Invalid Key",
53
+ }
54
+ gitlab_task = Gitlab(init)
55
+ pytest.raises(
56
+ scriptengine.exceptions.ScriptEngineTaskRunError,
57
+ gitlab_task.get_project_and_issue,
58
+ init["api_key"],
59
+ init["subject"],
60
+ )
61
+
62
+
63
+ def test_gitlab_get_template(tmp_path):
64
+ init = {
65
+ "src": str(tmp_path),
66
+ "local_dst": str(tmp_path),
67
+ "template": str(tmp_path / "gitlab.txt.j2"),
68
+ "subject": "Test Issue",
69
+ "api_key": "Invalid Key",
70
+ }
71
+ gitlab_task = Gitlab(init)
72
+ with pytest.raises(jinja2.exceptions.TemplateNotFound):
73
+ gitlab_task.get_template(init, init["template"])
74
+
75
+
76
+ class MockTemplateOrIssue:
77
+ def __init__(self):
78
+ self.globals = {}
79
+ self.web_url = ""
80
+
81
+ def render(self, **kwargs):
82
+ return str(kwargs)
83
+
84
+ def save(self):
85
+ return None
86
+
87
+ def upload(self, file_name, filepath=""):
88
+ return f"![{file_name}]({filepath})"
89
+
90
+
91
+ def test_gitlab_run(tmp_path):
92
+ init = {
93
+ "src": str(tmp_path),
94
+ "local_dst": str(tmp_path),
95
+ "template": str(tmp_path / "redmine.txt.j2"),
96
+ "subject": "Test Issue",
97
+ "api_key": "Invalid Key",
98
+ }
99
+ gitlab_task = Gitlab(init)
100
+ gitlab_task.get_presentation_list = Mock(return_value=[])
101
+ mock_object = MockTemplateOrIssue()
102
+ gitlab_task.get_template = Mock(return_value=mock_object)
103
+ gitlab_task.get_project_and_issue = Mock(return_value=(mock_object, mock_object))
104
+ with patch.object(gitlab_task, "log_debug") as mock:
105
+ gitlab_task.run(init)
106
+ mock.assert_called_with("Saving issue.")
107
+
108
+
109
+ def test_create_anchor():
110
+ test_string = "Precipitation - Evaporation (Annual Mean Climatology)"
111
+ gitlab_anchor = "precipitation-evaporation-annual-mean-climatology"
112
+ assert create_anchor(test_string) == gitlab_anchor