oncall-engine/engine/apps/grafana_plugin/tests/test_self_hosted_install.py
Yulya Artyukhina 381520ee13
Get rid of installation token + add a bunch of tests (#624)
* Get rid of installation token (for OSS installations)

This is done by being required to supply the grafana API URL as an
environment variable on the backend. Additionally, optionally an OnCall
API URL environment variable can be passed in to the frontend (this basically
allows completely skipping the need to configure anything).
- deduplicated a lot of the sync logic on the frontend + made
error message more useful and consistent
- Split PluginConfigPage component into several subcomponents
(making it easier to test each individual component)
- Moved RootWithLoader (from plugin/GrafanaPluginRootPage) into its own
subcomponent (making it easier to test)
- Added tests for pre-existing components that were touched:
  - PluginConfigPage component (and its new subcomponents)
  - state/plugin and state/rootBaseStore functions
  - apps.grafana_plugin django app

Helm changes:
- add GRAFANA_API_URL to oncall.env
- some yaml autoformatting changes
- remove reference to python manage.py issue_invite_for_the_frontend --override

Co-authored-by: Joey Orlando <joseph.t.orlando@gmail.com>
2022-11-21 16:26:00 +01:00

162 lines
6.6 KiB
Python

import json
from unittest.mock import patch
import pytest
from django.apps import apps
from django.conf import settings
from django.test import override_settings
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
GRAFANA_TOKEN = "TEST_TOKEN"
STACK_ID = 1
ORG_ID = 5
GRAFANA_API_URL = "hello.com"
LICENSE = "OpenSource"
STACK_SLUG = "asdfasdf"
ORG_SLUG = "hellooo"
ORG_TITLE = "nmvcnmvnmvc"
REGION_SLUG = "nmcvnmcvnmcvnmcv"
SELF_HOSTED_SETTINGS = {
"GRAFANA_API_URL": GRAFANA_API_URL,
"STACK_ID": STACK_ID,
"ORG_ID": ORG_ID,
"LICENSE": LICENSE,
"STACK_SLUG": STACK_SLUG,
"ORG_SLUG": ORG_SLUG,
"ORG_TITLE": ORG_TITLE,
"REGION_SLUG": REGION_SLUG,
}
UNABLE_TO_FIND_GRAFANA_ERROR_MSG = f"Unable to connect to the specified Grafana API - {GRAFANA_API_URL}"
UNAUTHED_GRAFANA_API_ERROR_MSG = (
f"You are not authorized to communicate with the specified Grafana API - {GRAFANA_API_URL}"
)
@pytest.fixture
def make_self_hosted_install_header():
def _make_instance_context_header(token):
return {
"HTTP_X-Instance-Context": json.dumps({"grafana_token": token}),
}
return _make_instance_context_header
@override_settings(LICENSE=settings.CLOUD_LICENSE_NAME)
def test_a_cloud_license_gets_an_unauthorized_error(make_self_hosted_install_header):
client = APIClient()
url = reverse("grafana-plugin:self-hosted-install")
response = client.post(url, format="json", **make_self_hosted_install_header(GRAFANA_TOKEN))
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.parametrize(
"grafana_api_status_code,expected_error_msg",
[
(status.HTTP_404_NOT_FOUND, UNABLE_TO_FIND_GRAFANA_ERROR_MSG),
(status.HTTP_401_UNAUTHORIZED, UNAUTHED_GRAFANA_API_ERROR_MSG),
(status.HTTP_401_UNAUTHORIZED, UNAUTHED_GRAFANA_API_ERROR_MSG),
],
)
@override_settings(SELF_HOSTED_SETTINGS=SELF_HOSTED_SETTINGS)
@patch("apps.grafana_plugin.views.self_hosted_install.GrafanaAPIClient")
def test_it_properly_handles_errors_from_the_grafana_api(
mocked_grafana_api_client, make_self_hosted_install_header, grafana_api_status_code, expected_error_msg
):
mocked_grafana_api_client.return_value.check_token.return_value = (None, {"status_code": grafana_api_status_code})
client = APIClient()
url = reverse("grafana-plugin:self-hosted-install")
response = client.post(url, format="json", **make_self_hosted_install_header(GRAFANA_TOKEN))
assert mocked_grafana_api_client.called_once_with(api_url=GRAFANA_API_URL, api_token=GRAFANA_TOKEN)
assert mocked_grafana_api_client.return_value.check_token.called_once_with()
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data["error"] == expected_error_msg
@override_settings(SELF_HOSTED_SETTINGS=SELF_HOSTED_SETTINGS)
@pytest.mark.django_db
@patch("apps.grafana_plugin.views.self_hosted_install.GrafanaAPIClient")
@patch("apps.grafana_plugin.views.self_hosted_install.sync_organization")
@patch("apps.grafana_plugin.views.self_hosted_install.Organization.provision_plugin")
@patch("apps.grafana_plugin.views.self_hosted_install.Organization.revoke_plugin")
def test_if_organization_exists_it_is_updated(
mocked_revoke_plugin,
mocked_provision_plugin,
mocked_sync_organization,
mocked_grafana_api_client,
make_self_hosted_install_header,
make_organization,
):
organization = make_organization(stack_id=STACK_ID, org_id=ORG_ID)
provision_plugin_response = {"stackId": STACK_ID, "orgId": ORG_ID, "onCallToken": "HELLOOO", "license": LICENSE}
mocked_provision_plugin.return_value = provision_plugin_response
mocked_grafana_api_client.return_value.check_token.return_value = (None, {"status_code": status.HTTP_200_OK})
client = APIClient()
url = reverse("grafana-plugin:self-hosted-install")
response = client.post(url, format="json", **make_self_hosted_install_header(GRAFANA_TOKEN))
assert mocked_grafana_api_client.called_once_with(api_url=GRAFANA_API_URL, api_token=GRAFANA_TOKEN)
assert mocked_grafana_api_client.return_value.check_token.called_once_with()
assert mocked_sync_organization.called_once_with(organization)
assert mocked_provision_plugin.called_once_with()
assert mocked_revoke_plugin.called_once_with()
assert response.status_code == status.HTTP_201_CREATED
assert response.data == {"error": None, **provision_plugin_response}
organization.refresh_from_db()
assert organization.grafana_url == GRAFANA_API_URL
assert organization.api_token == GRAFANA_TOKEN
@override_settings(SELF_HOSTED_SETTINGS=SELF_HOSTED_SETTINGS)
@pytest.mark.django_db
@patch("apps.grafana_plugin.views.self_hosted_install.GrafanaAPIClient")
@patch("apps.grafana_plugin.views.self_hosted_install.sync_organization")
@patch("apps.grafana_plugin.views.self_hosted_install.Organization.provision_plugin")
@patch("apps.grafana_plugin.views.self_hosted_install.Organization.revoke_plugin")
def test_if_organization_does_not_exist_it_is_created(
mocked_revoke_plugin,
mocked_provision_plugin,
mocked_sync_organization,
mocked_grafana_api_client,
make_self_hosted_install_header,
):
provision_plugin_response = {"stackId": STACK_ID, "orgId": ORG_ID, "onCallToken": "HELLOOO", "license": LICENSE}
mocked_provision_plugin.return_value = provision_plugin_response
mocked_grafana_api_client.return_value.check_token.return_value = (None, {"status_code": status.HTTP_200_OK})
client = APIClient()
url = reverse("grafana-plugin:self-hosted-install")
response = client.post(url, format="json", **make_self_hosted_install_header(GRAFANA_TOKEN))
Organization = apps.get_model("user_management", "Organization")
organization = Organization.objects.filter(stack_id=STACK_ID, org_id=ORG_ID).first()
assert mocked_grafana_api_client.called_once_with(api_url=GRAFANA_API_URL, api_token=GRAFANA_TOKEN)
assert mocked_grafana_api_client.return_value.check_token.called_once_with()
assert mocked_sync_organization.called_once_with(organization)
assert mocked_provision_plugin.called_once_with()
assert not mocked_revoke_plugin.called
assert response.status_code == status.HTTP_201_CREATED
assert response.data == {"error": None, **provision_plugin_response}
assert organization.stack_id == STACK_ID
assert organization.stack_slug == STACK_SLUG
assert organization.org_slug == ORG_SLUG
assert organization.org_title == ORG_TITLE
assert organization.region_slug == REGION_SLUG
assert organization.grafana_url == GRAFANA_API_URL
assert organization.api_token == GRAFANA_TOKEN