diff --git a/.gitignore b/.gitignore index 1cb6787..26be238 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ nosetests.xml coverage.xml *.cover .hypothesis/ +test-reports/ # Translations *.mo @@ -108,3 +109,5 @@ venv.bak/ # mypy .mypy_cache/ +# Editors +.idea/ diff --git a/grafana_api/api/dashboard.py b/grafana_api/api/dashboard.py index 2380c23..c38e9f5 100644 --- a/grafana_api/api/dashboard.py +++ b/grafana_api/api/dashboard.py @@ -22,6 +22,14 @@ def update_dashboard(self, dashboard): :param dashboard: :return: """ + + # When the "folderId" is not available within the dashboard payload, + # populate it from the nested "meta" object, if given. + if "folderId" not in dashboard: + if "meta" in dashboard and "folderId" in dashboard["meta"]: + dashboard = dashboard.copy() + dashboard["folderId"] = dashboard["meta"]["folderId"] + put_dashboard_path = "/dashboards/db" r = self.api.POST(put_dashboard_path, json=dashboard) return r diff --git a/test/api/test_dashboard.py b/test/api/test_dashboard.py index db0edd9..011abf1 100644 --- a/test/api/test_dashboard.py +++ b/test/api/test_dashboard.py @@ -37,6 +37,9 @@ def test_get_dashboard(self, m): @requests_mock.Mocker() def test_update_dashboard(self, m): + """ + Verify a general dashboard update. + """ m.post( "http://localhost/api/dashboards/db", json={ @@ -65,6 +68,53 @@ def test_update_dashboard(self, m): self.assertEqual(dashboard["uid"], "cIBgcSjkk") self.assertEqual(dashboard["status"], "success") + @requests_mock.Mocker() + def test_update_dashboard_roundtrip_folder_1(self, m): + """ + Verify that a dashboard update will use the "folderId" + from the nested "meta" object. + + This is important when roundtripping dashboard payloads. + """ + m.post( + "http://localhost/api/dashboards/db", + json={} + ) + self.cli.dashboard.update_dashboard({ + "meta": { + "folderId": 123, + }, + "dashboard": { + }, + }) + + self.assertEqual(m.last_request.json()["folderId"], 123) + + @requests_mock.Mocker() + def test_update_dashboard_roundtrip_folder_2(self, m): + """ + Verify that a dashboard update will use the "folderId" + from the toplevel dashboard payload, even if it is present + within the nested "meta" object. + + This is important when roundtripping dashboard payloads and + intentionally wanting to move the dashboard to a different folder. + """ + m.post( + "http://localhost/api/dashboards/db", + json={} + ) + self.cli.dashboard.update_dashboard({ + "meta": { + "folderId": 123, + }, + "dashboard": { + }, + "folderId": 456, + }) + + self.assertEqual(m.last_request.json()["folderId"], 456) + @requests_mock.Mocker() def test_get_home_dashboard(self, m): m.get(