Repository: BSC-ES/autosubmit
Pull request #2174: test for the function build_legends in monitor/diagram.py
Author: login: VindeeR
Labels: name: enhancement
description: New feature or request
Created: 2025-03-04T13:43:26Z | Merged: 2025-03-05T11:11:23Z

-Test function build_legends
-Adding docstring to function
-restructuring type hint


Diff:
diff --git a/autosubmit/monitor/diagram.py b/autosubmit/monitor/diagram.py
index b1c9cfbd3..cc5a20431 100644
--- a/autosubmit/monitor/diagram.py
+++ b/autosubmit/monitor/diagram.py
@@ -356,9 +356,21 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics,
+                  general_stats: list[tuple[str, str]]) -> int:
+    """build_legends Function
+
+    :param plot: Subplot arrangement part of a figure
+    :type plot: Any
+    :param rects: A string that contains the legends for the plot
+    :type rects: list[list[str]]
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :type experiment_stats: Statistics
+    :param general_stats: list that contains the status of the jobs
+    :type general_stats: list[tuple[str, str]]
+    :returns: Return the length of the legends built
+    :rtype: int
+    """
     # Main legend with colourful rectangles
     legend_rects = [[rect[0] for rect in rects]]
 
@@ -386,6 +398,7 @@ def build_legends(plot, rects, experiment_stats, general_stats):
     legends = create_legends(plot, legend_rects, legend_titles, legend_locs, legend_handlelengths)
     for legend in legends:
         plt.gca().add_artist(legend)
+    return len(legends)
 
 
 def create_legends(plot, rects, titles, locs, handlelengths):
diff --git a/test/unit/test_diagram.py b/test/unit/test_diagram.py
index a210822e4..bfb039d88 100644
--- a/test/unit/test_diagram.py
+++ b/test/unit/test_diagram.py
@@ -36,6 +36,7 @@ def test_job_data():
     assert job_data.values() == ['', datetime.timedelta(0), datetime.timedelta(0), '']
     assert job_data.number_of_columns() == 4
 
+
 def test_job_agg_data():
     """ function to test the Class JobAggData inside autosubmit/monitor/diagram.py """
     job_agg = JobAggData()
@@ -44,8 +45,10 @@ def test_job_agg_data():
                                 datetime.timedelta(0), datetime.timedelta(0)]
     assert job_agg.number_of_columns() == 6
 
+
 def test_create_csv_stats(tmpdir):
     """ function to test the Function create_csv_stats inside autosubmit/monitor/diagram.py """
+
     jobs_data = [
         Job('test', "a000", "COMPLETED", 200),
         Job('test', "a000", "COMPLETED", 200),
@@ -65,6 +68,28 @@ def test_create_csv_stats(tmpdir):
     assert tmpdir.exists()
 
 
+def test_build_legends(mocker):
+    """ function to test the function build_legends inside autosubmit/monitor/diagram.py """
+
+    jobs_data = [
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "FAILED", 10)
+    ]
+    date_ini = datetime.datetime.now()
+    date_fin = date_ini + datetime.timedelta(0.10)
+    queue_time_fixes = {'test': 5}
+
+    statistics = diagram.populate_statistics(jobs_data, date_ini, date_fin, queue_time_fixes)
+    react = [['dummy'], [''], ['test']]
+    general_stats = [('status', 'status2'), ('status', 'status2'), ('status', 'status2')]
+    plot = mocker.Mock()
+
+    number_of_legends = diagram.build_legends(plot, react, statistics, general_stats)
+    assert plot.legend.call_count == number_of_legends
+
+
 @pytest.mark.parametrize("job_stats, failed_jobs, failed_jobs_dict, num_plots, result", [
     (
             ["COMPLETED", "COMPLETED", "COMPLETED", "FAILED"],
@@ -101,10 +126,11 @@ def test_create_csv_stats(tmpdir):
             40,
             True
     ),
-], ids=['all run', 'divided by zero', 'run with continue', 'fail job_dict', 'no run']
-                         )
+],
+ids=['all run', 'divided by zero', 'run with continue', 'fail job_dict', 'no run'])
 def test_create_bar_diagram(job_stats, failed_jobs, failed_jobs_dict, num_plots, result):
     """ function to test the function create_bar_diagram inside autosubmit/monitor/diagram.py """
+
     jobs_data = [
         Job('test', "a000", "COMPLETED", 200),
         Job('test', "a000", "COMPLETED", 200),
@@ -113,7 +139,8 @@ def test_create_bar_diagram(job_stats, failed_jobs, failed_jobs_dict, num_plots,
     ]
     date_ini = datetime.datetime.now()
     date_fin = date_ini + datetime.timedelta(0.10)
-    queue_time_fixes = ['test', 5]
+
+    queue_time_fixes = {'test', 5}
 
     status = ["COMPLETED", "COMPLETED", "COMPLETED", "FAILED"]
     statistics = diagram.populate_statistics(jobs_data, date_ini, date_fin, queue_time_fixes)


Reviews:
user: login: kinow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-04T13:44:59Z
user: login: kinow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-04T13:56:21Z
user: login: kinow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-04T14:39:09Z
user: login: kinow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-04T18:03:27Z
user: login: kinow
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-04T18:12:39Z
user: login: kinow
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-05T08:23:06Z
user: login: VindeeR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T08:29:30Z

Review comments:
diff_hunk: @@ -338,9 +338,17 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """
+        build_legends Function
+        :param
+        :plot: Any
+        :rects: List[str]
+        :experiment_stats: Statistics of the jobs of the experiment
+        :general_stats: List[str] of status of the jobs
+        :return: None
path: autosubmit/monitor/diagram.py
user: login: kinow
body: Wrong indentation
created_at: 2025-03-04T13:44:52Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,17 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """
+        build_legends Function
+        :param
+        :plot: Any
+        :rects: List[str]
+        :experiment_stats: Statistics of the jobs of the experiment
+        :general_stats: List[str] of status of the jobs
+        :return: None
path: autosubmit/monitor/diagram.py
user: login: kinow
body: Not quite there, yet.

Everything is left-aligned along the quotes. Example from Python source code: https://github.com/python/cpython/blob/80e6d3ec4972220587c8b883161311a49ea8d0ff/Lib/asyncio/queues.py#L253-L262

The params are also left-aligned. There is no indentation in the docs, unless you need to keep it to render sphinx code blocks, or to continue a previous statement. Example from pip, https://github.com/pypa/pip/blob/c1100ee6ad9c7812687285db741e8c79f359aace/src/pip/_internal/operations/prepare.py#L146-L160
created_at: 2025-03-04T13:56:21Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,18 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """build_legends Function
 
+    :param
+    :plot: Any
path: autosubmit/monitor/diagram.py
user: login: kinow
body: I think there's an extra blank line here.
created_at: 2025-03-04T14:32:58Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,18 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
path: autosubmit/monitor/diagram.py
user: login: kinow
body: I think `rects` is `list[list[str]]`?
created_at: 2025-03-04T14:33:07Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,18 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """build_legends Function
 
+    :param
+    :plot: Any
+    :rects: List[str]
path: autosubmit/monitor/diagram.py
user: login: kinow
body: Missing `param` in front of it? In PyCharm you can preview the generated docs by hovering over the function, e.g.

![image](https://github.com/user-attachments/assets/88410537-5261-4071-b8c4-d0b57c090454)

So you can check if your changes are rendering correctly.
created_at: 2025-03-04T14:35:14Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,18 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """build_legends Function
 
+    :param
+    :plot: Any
+    :rects: List[str]
+    :experiment_stats: Statistics of the jobs of the experiment
+    :general_stats: List[str] of status of the jobs
path: autosubmit/monitor/diagram.py
user: login: kinow
body: Missing `param` in these too.
created_at: 2025-03-04T14:35:56Z
author_association: MEMBER
diff_hunk: @@ -338,9 +338,18 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
+def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
+                  general_stats: List[str]) -> None:
+    """build_legends Function
 
+    :param
+    :plot: Any
+    :rects: List[str]
+    :experiment_stats: Statistics of the jobs of the experiment
+    :general_stats: List[str] of status of the jobs
+
path: autosubmit/monitor/diagram.py
user: login: kinow
body: The white space between params and return/raises/etc is normally not used, but doesn't really matter as the generated docs will ignore it.
created_at: 2025-03-04T14:36:39Z
author_association: MEMBER
diff_hunk: @@ -41,3 +44,24 @@ def test_job_agg_data():
     assert job_agg.values() == [{}, 0, datetime.timedelta(0), datetime.timedelta(0),
                                 datetime.timedelta(0), datetime.timedelta(0)]
     assert job_agg.number_of_columns() == 6
+
+
+def test_build_legends():
+    """ function to test the function create_bar_diagram inside autosubmit/monitor/diagram.py """
+    jobs_data = [
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "COMPLETED", 200),
+        Job('test', "a000", "FAILED", 10)
+    ]
+
+
+    date_ini = datetime.datetime.now()
+    date_fin = date_ini + datetime.timedelta(0.10)
+    queue_time_fixes = ['test', 5]
+
+    react = (['dummy'], [''], ['test'])
+    general_stats = [('status', 'status2'),('status', 'status2'),('status', 'status2')]
+
+    statistics = diagram.populate_statistics(jobs_data, date_ini, date_fin, queue_time_fixes)
+    assert diagram.build_legends(Mock(), react, statistics, general_stats) is None
path: test/unit/test_diagram.py
user: login: kinow
body: I think this is not correct. `build_legends` alters the state of `plot` (and maybe other args), and returns `None`. Testing `is None` would succeed whether `diagram.build_legends` did what we expect or not (unless it raises an exception... which may or may not be used by design here).

Better to test that a legend was built.
created_at: 2025-03-04T14:39:05Z
author_association: MEMBER
diff_hunk: @@ -347,9 +347,17 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics,
+                  general_stats: list[tuple[str, str]]) -> int:
+    """build_legends Function
+
+    :param plot: Any
+    :param rects: list[list[str]]
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :param general_stats: list[tuple[str, str]] of status of the jobs
+    :param
path: autosubmit/monitor/diagram.py
user: login: kinow
body: empty :param?
created_at: 2025-03-04T18:03:27Z
author_association: MEMBER
diff_hunk: @@ -347,9 +347,17 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics,
+                  general_stats: list[tuple[str, str]]) -> int:
+    """build_legends Function
+
+    :param plot: Any
+    :param rects: list[list[str]]
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :param general_stats: list[tuple[str, str]] of status of the jobs
path: autosubmit/monitor/diagram.py
user: login: kinow
body: With this syntax for docstring... it's a bit uglier.

```python
"""
:param plot: What is plot goes here
:type plot: Any
:param rects: What is rects?
:type rects: list[list[str]]
:return: what is returned? Sometimes if it's None then it is ignored/not included
:rtype: None/int/etc
"""
```

This is called reStructuredText format for docstrings. That's the most common format found in Autosubmit code base (90% of comments or more?). So that's what I use too.

You can also write using Google style, or epytext, or numpy..* refs:

* https://www.softwaretestinghelp.com/python-docstring-tutorial/
* https://sphinxcontrib-napoleon.readthedocs.io/en/latest/index.html
* https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
* https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html

What you have looks a bit like Numpy, I think. But it's also not valid. It's more similar to restructuredtext, but missing some parts. I think we must all use restructuredtext for now, as that's what we have in most of the code. 
created_at: 2025-03-04T18:12:38Z
author_association: MEMBER
diff_hunk: @@ -347,9 +347,21 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics,
+                  general_stats: list[tuple[str, str]]) -> int:
+    """build_legends Function
+
+    :param plot: Subplot arrangement part of a figure
+    :type plot: Any
+    :param rects: A string that contains the legends for the plot
+    :type rects: list[list[str]]
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :type experiment_stats: Statistics
+    :param general_stats: list that contains the status of the jobs
+    :type general_stats: list[tuple[str, str]]
+    :returns: Return the length of the legends built
+    :rtype: int
+    """
path: autosubmit/monitor/diagram.py
user: login: kinow
body: :ok_hand: :clap: 
created_at: 2025-03-05T08:22:55Z
author_association: MEMBER
diff_hunk: @@ -347,9 +347,21 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot, rects, experiment_stats, general_stats):
-    # type: (plt.figure, List[plt.bar], Statistics, List[str]) -> None
-
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics,
+                  general_stats: list[tuple[str, str]]) -> int:
+    """build_legends Function
+
+    :param plot: Subplot arrangement part of a figure
+    :type plot: Any
+    :param rects: A string that contains the legends for the plot
+    :type rects: list[list[str]]
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :type experiment_stats: Statistics
+    :param general_stats: list that contains the status of the jobs
+    :type general_stats: list[tuple[str, str]]
+    :returns: Return the length of the legends built
+    :rtype: int
+    """
path: autosubmit/monitor/diagram.py
user: login: VindeeR
body: It was tricky but I finally got it 😭
Thanks
created_at: 2025-03-05T08:29:30Z
author_association: CONTRIBUTOR

PR comments:
user: login: codecov-commenter
created_at: 2025-03-04T14:01:34Z
body: ## [Codecov](https://app.codecov.io/gh/BSC-ES/autosubmit/pull/2174?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 51.61%. Comparing base [(`ec59743`)](https://app.codecov.io/gh/BSC-ES/autosubmit/commit/ec59743d738ff15a275030c51c1f2a3742991a08?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES) to head [(`bf1f619`)](https://app.codecov.io/gh/BSC-ES/autosubmit/commit/bf1f619a66d212a796987670744e644bd27c1e4d?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES).
> Report is 2 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #2174      +/-   ##
==========================================
+ Coverage   51.48%   51.61%   +0.12%     
==========================================
  Files          73       73              
  Lines       17682    17683       +1     
  Branches     3436     3436              
==========================================
+ Hits         9104     9127      +23     
+ Misses       7779     7756      -23     
- Partials      799      800       +1     
```

| [Flag](https://app.codecov.io/gh/BSC-ES/autosubmit/pull/2174/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES) | Coverage Δ | |
|---|---|---|
| [fast-tests](https://app.codecov.io/gh/BSC-ES/autosubmit/pull/2174/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES) | `51.61% <100.00%> (+0.12%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/BSC-ES/autosubmit/pull/2174?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BSC-ES).

author_association: NONE
user: login: kinow
created_at: 2025-03-04T14:43:43Z
body: @VindeeR here's a tentative update to the test to test that the legends were created (that function could do with some rework, I think -- inverting the control and passing the list of legends/headers, so we don't need to return the amount created -- e.g. if we change the columns, that would break the test without returning the len(legends...)).

```diff
diff --git a/autosubmit/monitor/diagram.py b/autosubmit/monitor/diagram.py
index a7078d5b..76be0210 100644
--- a/autosubmit/monitor/diagram.py
+++ b/autosubmit/monitor/diagram.py
@@ -338,17 +338,15 @@ def create_csv_stats(exp_stats: Statistics, jobs_list: List[Job],
                 job_names[i], start_times[i], end_times[i], queuing_times[i], running_times[i]))
 
 
-def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
-                  general_stats: List[str]) -> None:
+def build_legends(plot: Any, rects: list[list[str]], experiment_stats: Statistics, general_stats: List[str]) -> int:
     """build_legends Function
 
-    :param
-    :plot: Any
-    :rects: List[str]
-    :experiment_stats: Statistics of the jobs of the experiment
-    :general_stats: List[str] of status of the jobs
-
-    :return: None
+    :param plot: Any
+    :param rects: list[list[str]]s
+    :param experiment_stats: Statistics of the jobs of the experiment
+    :param general_stats: List[str] of status of the jobs
+    :return: The number of legends created
+    :rtype: int
     """
     # Main legend with colourful rectangles
     legend_rects = [[rect[0] for rect in rects]]
@@ -378,6 +376,8 @@ def build_legends(plot: Any, rects: list[str], experiment_stats: Statistics,
     for legend in legends:
         plt.gca().add_artist(legend)
 
+    return len(legends)
+
 
 def create_legends(plot, rects, titles, locs, handlelengths):
     legends = []
diff --git a/test/unit/test_diagram.py b/test/unit/test_diagram.py
index 4249dcf1..a360b19e 100644
--- a/test/unit/test_diagram.py
+++ b/test/unit/test_diagram.py
@@ -46,7 +46,7 @@ def test_job_agg_data():
     assert job_agg.number_of_columns() == 6
 
 
-def test_build_legends():
+def test_build_legends(mocker):
     """ function to test the function create_bar_diagram inside autosubmit/monitor/diagram.py """
     jobs_data = [
         Job('test', "a000", "COMPLETED", 200),
@@ -60,8 +60,11 @@ def test_build_legends():
     date_fin = date_ini + datetime.timedelta(0.10)
     queue_time_fixes = ['test', 5]
 
-    react = (['dummy'], [''], ['test'])
+    react = [['dummy'], [''], ['test']]
     general_stats = [('status', 'status2'),('status', 'status2'),('status', 'status2')]
 
     statistics = diagram.populate_statistics(jobs_data, date_ini, date_fin, queue_time_fixes)
-    assert diagram.build_legends(Mock(), react, statistics, general_stats) is None
+    plot = mocker.Mock()
+    # for each legend, matplotlib code will cause a call to ``plot.legend``.
+    number_of_legends = diagram.build_legends(plot, react, statistics, general_stats)
+    assert plot.legend.call_count == number_of_legends

```
author_association: MEMBER
user: login: kinow
created_at: 2025-03-05T08:25:32Z
body: Just need to resolve Git conflicts, then ready to be merged.
author_association: MEMBER