Skip to content

Commit

Permalink
Refactor unit tests (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
arturo-seijas authored Nov 29, 2023
1 parent 17d123a commit b62e655
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 160 deletions.
191 changes: 89 additions & 102 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@
# See LICENSE file for licensing details.

"""Unit tests."""
# pylint: disable=protected-access

import secrets
from unittest.mock import MagicMock, patch

import ops
from ops.testing import Harness

from charm import SmtpIntegratorOperatorCharm

MINIMAL_CHARM_CONFIG = {
"host": "smtp.example",
"port": 25,
}
MINIMAL_CHARM_CONFIG_WITH_PASSWORD = {
**MINIMAL_CHARM_CONFIG,
"password": secrets.token_hex(),
}


def test_unconfigured_charm_reaches_blocked_status():
"""
arrange: set up a charm.
act: trigger a configuration change missing required configs.
arrange: set up a charm without configuration.
act: none
assert: the charm reaches BlockedStatus.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
Expand All @@ -24,8 +34,8 @@ def test_unconfigured_charm_reaches_blocked_status():

def test_misconfigured_port_charm_reaches_blocked_status():
"""
arrange: set up a charm.
act: trigger a configuration change with an invalid port.
arrange: set up a charm with an invalid port.
act: none
assert: the charm reaches BlockedStatus.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
Expand All @@ -41,15 +51,14 @@ def test_misconfigured_port_charm_reaches_blocked_status():

def test_misconfigured_auth_type_charm_reaches_blocked_status():
"""
arrange: set up a charm.
act: trigger a configuration change with an invalid auth type.
arrange: set up a charm ith an invalid auth type.
act: none
assert: the charm reaches BlockedStatus.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.update_config(
{
"host": "smtp.example",
"port": 25,
**MINIMAL_CHARM_CONFIG,
"auth_type": "nonexisting",
}
)
Expand All @@ -59,15 +68,14 @@ def test_misconfigured_auth_type_charm_reaches_blocked_status():

def test_misconfigured_transport_security_charm_reaches_blocked_status():
"""
arrange: set up a charm.
act: trigger a configuration change with an invalid transport security.
arrange: set up a charm with an invalid transport security.
act: none
assert: the charm reaches BlockedStatus.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.update_config(
{
"host": "smtp.example",
"port": 25,
**MINIMAL_CHARM_CONFIG,
"transport_security": "nonexisting",
}
)
Expand All @@ -77,100 +85,100 @@ def test_misconfigured_transport_security_charm_reaches_blocked_status():

def test_charm_reaches_active_status():
"""
arrange: set up a charm.
arrange: set up a charm with minimal valid configuration.
act: trigger a configuration change with the required configs.
assert: the charm reaches ActiveStatus.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.update_config(
{
"host": "smtp.example",
"port": 25,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG)
harness.begin()
harness.charm.on.config_changed.emit()
assert harness.model.unit.status == ops.ActiveStatus()


def test_legacy_relation_joined_when_leader():
def test_legacy_relation_joined_populates_data():
"""
arrange: set up a configured charm and set leadership for the unit.
act: add a relation.
assert: the relation gets populated with the SMTP data.
arrange: set up a charm with valid configuration and leadership for the unit.
act: add an smtp-legacy relation.
assert: the smtp-legacy relation gets populated with the SMTP data.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
host = "smtp.example"
port = 25
password = "somepassword" # nosec
harness.update_config(
{
"host": host,
"port": port,
"password": password,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG_WITH_PASSWORD)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp-legacy", "example")
data = harness.model.get_relation("smtp-legacy").data[harness.model.app]
assert data["host"] == MINIMAL_CHARM_CONFIG_WITH_PASSWORD["host"]
assert data["port"] == str(MINIMAL_CHARM_CONFIG_WITH_PASSWORD["port"])
assert data["password"] == MINIMAL_CHARM_CONFIG_WITH_PASSWORD["password"]


def test_legacy_relation_joined_doesnt_populate_password_id():
"""
arrange: set up a charm with valid configuration and leadership for the unit.
act: add an smtp-legacy relation.
assert: the smtp-legacy relation does not get populated with the password_id.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
harness.update_config(MINIMAL_CHARM_CONFIG_WITH_PASSWORD)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp-legacy", "example")
data = harness.model.get_relation("smtp-legacy").data[harness.model.app]
assert data["host"] == host
assert data["port"] == str(port)
assert data["password"] == password
assert "password_id" not in data


@patch.object(ops.JujuVersion, "from_environ")
def test_relation_joined_when_leader_and_secrets(mock_juju_env):
def test_relation_joined_when_secrets_enabled_populates_data(mock_juju_env):
"""
arrange: set up a configured charm mimicking Juju 3 and set leadership for the unit.
act: add a relation.
assert: the relation gets populated with the SMTP data.
arrange: set up a charm with valid configuration mimicking Juju 3 and leadership for the unit.
act: add an smtp relation.
assert: the smtp relation gets populated with the SMTP data.
"""
mock_juju_env.return_value = MagicMock(has_secrets=True)
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
host = "smtp.example"
port = 25
password = "somepassword" # nosec
harness.update_config(
{
"host": host,
"port": port,
"password": password,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG_WITH_PASSWORD)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp", "example")
data = harness.model.get_relation("smtp").data[harness.model.app]
assert data["host"] == host
assert data["port"] == str(port)
assert "password" not in data
assert data["host"] == MINIMAL_CHARM_CONFIG_WITH_PASSWORD["host"]
assert data["port"] == str(MINIMAL_CHARM_CONFIG_WITH_PASSWORD["port"])
assert data["password_id"] is not None


@patch.object(ops.JujuVersion, "from_environ")
def test_relation_joined_when_leader_and_no_secrets(mock_juju_env):
def test_relation_joined_when_secrets_enabled_doesnt_populate_password(mock_juju_env):
"""
arrange: set up a configured charm mimicking Juju 2 and set leadership for the unit.
act: add a relation.
assert: the relation does not get populated with the SMTP data.
arrange: set up a charm with valid configuration mimicking Juju 3 and leadership for the unit.
act: add an smtp relation.
assert: the smtp relation does not populate with the password.
"""
mock_juju_env.return_value = MagicMock(has_secrets=True)
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
harness.update_config(MINIMAL_CHARM_CONFIG_WITH_PASSWORD)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp", "example")
data = harness.model.get_relation("smtp").data[harness.model.app]
assert "password" not in data


@patch.object(ops.JujuVersion, "from_environ")
def test_relation_joined_when_no_secrets_enabled(mock_juju_env):
"""
arrange: set up a charm with valid configuration mimicking Juju 2 and leadership for the unit.
act: add an smtp relation.
assert: the smtp relation does not get populated with the SMTP data.
"""
mock_juju_env.return_value = MagicMock(has_secrets=False)
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
host = "smtp.example"
port = 25
password = "somepassword" # nosec
harness.update_config(
{
"host": host,
"port": port,
"password": password,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG_WITH_PASSWORD)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp", "example")
Expand All @@ -179,49 +187,35 @@ def test_relation_joined_when_leader_and_no_secrets(mock_juju_env):


@patch.object(ops.JujuVersion, "from_environ")
def test_relation_joined_when_leader_and_no_password(mock_juju_env):
def test_relation_joined_when_no_password_configured(mock_juju_env):
"""
arrange: set up a configured charm mimicking Juju 3 and set leadership for the unit.
act: add a relation.
assert: the relation gets populated with the SMTP data.
arrange: set up a configured charm mimicking Juju 3 and leadership for the unit.
act: add an smtp relation.
assert: the relation gets populated with the SMTP data and the password_id is not present.
"""
mock_juju_env.return_value = MagicMock(has_secrets=True)
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(True)
host = "smtp.example"
port = 25
harness.update_config(
{
"host": host,
"port": port,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp", "example")
data = harness.model.get_relation("smtp").data[harness.model.app]
assert data["host"] == host
assert data["port"] == str(port)
assert data["host"] == MINIMAL_CHARM_CONFIG["host"]
assert data["port"] == str(MINIMAL_CHARM_CONFIG["port"])
assert "password" not in data
assert "password_id" not in data


def test_legacy_relation_joined_when_not_leader():
"""
arrange: set up a charm mimicking Juju 3 and unset leadership for the unit.
act: add a relation.
assert: the relation does not get populated with the SMTP data.
act: add an smtp-legacy relation.
assert: the smtp-legacy relation does not get populated with the SMTP data.
"""
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(False)
host = "smtp.example"
port = 25
harness.update_config(
{
"host": host,
"port": port,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp-legacy", "example")
Expand All @@ -233,20 +227,13 @@ def test_legacy_relation_joined_when_not_leader():
def test_relation_joined_when_not_leader(mock_juju_env):
"""
arrange: set up a charm mimicking Juju 3 and unset leadership for the unit.
act: add a relation.
assert: the relation does not get populated with the SMTP data.
act: add an smtp relation.
assert: the smtp relation does not get populated with the SMTP data.
"""
mock_juju_env.return_value = MagicMock(has_secrets=True)
harness = Harness(SmtpIntegratorOperatorCharm)
harness.set_leader(False)
host = "smtp.example"
port = 25
harness.update_config(
{
"host": host,
"port": port,
}
)
harness.update_config(MINIMAL_CHARM_CONFIG)
harness.begin()
harness.charm.on.config_changed.emit()
harness.add_relation("smtp", "example")
Expand Down
Loading

0 comments on commit b62e655

Please sign in to comment.