Skip to content

Commit 634a6a9

Browse files
committed
Update tests
1 parent 814d187 commit 634a6a9

File tree

5 files changed

+113
-16
lines changed

5 files changed

+113
-16
lines changed

backend/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ DJANGO_ALGOLIA_WRITE_API_KEY=None
44
DJANGO_ALLOWED_HOSTS=*
55
DJANGO_AWS_ACCESS_KEY_ID=None
66
DJANGO_AWS_KMS_KEY_ID=None
7-
DJANGO_AWS_REGION=None
7+
DJANGO_AWS_REGION=your-aws-region
88
DJANGO_AWS_SECRET_ACCESS_KEY=None
99
DJANGO_CONFIGURATION=Test
1010
DJANGO_DB_HOST=None

backend/apps/common/clients.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ def __init__(self):
2929
self.client = boto3.client(
3030
"kms",
3131
region_name=settings.AWS_REGION,
32-
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
33-
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
3432
)
3533

3634
def decrypt(self, text: bytes) -> str:

backend/settings/base.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ class Base(Configuration):
1515

1616
ALLOWED_HOSTS = values.ListValue()
1717
AUTH_USER_MODEL = "nest.User"
18-
AWS_ACCESS_KEY_ID = None
19-
AWS_KMS_KEY_ID = None
20-
AWS_REGION = None
21-
AWS_SECRET_ACCESS_KEY = None
18+
AWS_KMS_KEY_ID = values.Value(environ_name="AWS_KMS_KEY_ID", default=None)
19+
AWS_ACCESS_KEY_ID = values.SecretValue(environ_name="AWS_ACCESS_KEY_ID", default=None)
20+
AWS_SECRET_ACCESS_KEY = values.SecretValue(environ_name="AWS_SECRET_ACCESS_KEY", default=None)
21+
AWS_REGION = values.Value(environ_name="AWS_REGION", default=None)
2222
CORS_ALLOW_CREDENTIALS = True
2323
DEBUG = False
2424
GITHUB_APP_ID = None
@@ -29,12 +29,6 @@ class Base(Configuration):
2929

3030
IS_AWS_KMS_ENABLED = values.BooleanValue(environ_name="IS_AWS_KMS_ENABLED", default=False)
3131

32-
if IS_AWS_KMS_ENABLED:
33-
AWS_KMS_KEY_ID = values.Value(environ_name="AWS_KMS_KEY_ID")
34-
AWS_ACCESS_KEY_ID = values.SecretValue(environ_name="AWS_ACCESS_KEY_ID")
35-
AWS_SECRET_ACCESS_KEY = values.SecretValue(environ_name="AWS_SECRET_ACCESS_KEY")
36-
AWS_REGION = values.Value(environ_name="AWS_REGION")
37-
3832
IS_GOOGLE_AUTH_ENABLED = all(
3933
value not in (None, "None", "")
4034
for value in (GOOGLE_AUTH_CLIENT_ID, GOOGLE_AUTH_CLIENT_SECRET, GOOGLE_AUTH_REDIRECT_URI)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""Test cases for API clients."""
2+
3+
from unittest.mock import Mock, patch
4+
5+
import pytest
6+
from django.test.utils import override_settings
7+
8+
from apps.common.clients import KmsClient
9+
10+
11+
class TestKmsClient:
12+
"""Test cases for KMS client."""
13+
14+
@pytest.fixture(autouse=True)
15+
def setup(self):
16+
"""Set up mock KMS client."""
17+
with patch("boto3.client") as mock_boto3_client:
18+
self.mock_boto3_client = mock_boto3_client
19+
self.mock_kms_client = Mock()
20+
self.mock_boto3_client.return_value = self.mock_kms_client
21+
self.kms_client = KmsClient()
22+
23+
@override_settings(AWS_REGION="us-west-2", AWS_KMS_KEY_ID="test_key_id")
24+
def test_encrypt(self):
25+
"""Test encryption."""
26+
plaintext = "test"
27+
self.mock_kms_client.encrypt.return_value = {"CiphertextBlob": b"encrypted"}
28+
ciphertext = self.kms_client.encrypt(plaintext)
29+
assert ciphertext != plaintext
30+
self.mock_kms_client.encrypt.assert_called_once_with(
31+
Plaintext=plaintext.encode("utf-8"), KeyId="test_key_id"
32+
)
33+
34+
@override_settings(AWS_REGION="us-west-2", AWS_KMS_KEY_ID="test_key_id")
35+
def test_decrypt(self):
36+
"""Test decryption."""
37+
self.mock_kms_client.decrypt.return_value = {"Plaintext": b"test"}
38+
decrypted = self.kms_client.decrypt(b"encrypted")
39+
assert decrypted == "test"
40+
self.mock_kms_client.decrypt.assert_called_once_with(
41+
CiphertextBlob=b"encrypted", KeyId="test_key_id"
42+
)

backend/tests/apps/slack/models/google_auth_test.py

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def setUp(self):
2424
self.valid_refresh_token = b"valid_refresh_token"
2525
self.expired_time = timezone.now() - timedelta(hours=1)
2626
self.future_time = timezone.now() + timedelta(hours=1)
27+
with patch("boto3.client") as mock_boto3_client:
28+
self.mock_boto3_client = mock_boto3_client
29+
self.mock_kms_client = Mock()
30+
self.mock_boto3_client.return_value = self.mock_kms_client
2731

2832
def test_google_auth_creation(self):
2933
"""Test GoogleAuth model creation."""
@@ -261,8 +265,15 @@ def test_authenticate_callback_google_auth_disabled(self):
261265
with pytest.raises(ValueError, match="Google OAuth client ID"):
262266
GoogleAuth.authenticate_callback(auth_response={}, member_id=4)
263267

268+
@override_settings(IS_AWS_KMS_ENABLED=False, IS_GOOGLE_AUTH_ENABLED=True)
269+
def test_authenticate_callback_kms_disabled(self):
270+
"""Test authenticate_callback raises error when AWS KMS is disabled."""
271+
with pytest.raises(ValueError, match="AWS KMS is not enabled"):
272+
GoogleAuth.authenticate_callback(auth_response={}, member_id=4)
273+
264274
@override_settings(
265275
IS_GOOGLE_AUTH_ENABLED=True,
276+
IS_AWS_KMS_ENABLED=True,
266277
GOOGLE_AUTH_CLIENT_ID="test_client_id",
267278
GOOGLE_AUTH_CLIENT_SECRET="test_client_secret", # noqa: S106
268279
GOOGLE_AUTH_REDIRECT_URI="http://localhost:8000/callback",
@@ -271,8 +282,9 @@ def test_authenticate_callback_google_auth_disabled(self):
271282
@patch("apps.slack.models.google_auth.GoogleAuth.objects.get_or_create")
272283
@patch("apps.slack.models.google_auth.GoogleAuth.save")
273284
@patch("apps.slack.models.google_auth.Member.objects.get")
285+
@patch("apps.slack.models.google_auth.GoogleAuth.get_kms_client")
274286
def test_authenticate_callback_success(
275-
self, mock_member_get, mock_save, mock_get_or_create, mock_get_flow
287+
self, mock_get_kms_client, mock_member_get, mock_save, mock_get_or_create, mock_get_flow
276288
):
277289
"""Test successful authenticate_callback."""
278290
mock_credentials = Mock()
@@ -285,17 +297,22 @@ def test_authenticate_callback_success(
285297
mock_member_get.return_value = self.member
286298
mock_get_flow.return_value = mock_flow_instance
287299
mock_get_or_create.return_value = (GoogleAuth(member=self.member), False)
300+
301+
mock_get_kms_client.return_value.encrypt.return_value = b"encrypted_token"
288302
result = GoogleAuth.authenticate_callback({}, member_id=self.member.slack_user_id)
289303

290-
assert result.access_token == b"token"
291-
assert result.refresh_token == b"refresh_token"
304+
assert result.access_token == b"encrypted_token"
305+
assert result.refresh_token == b"encrypted_token"
292306
assert result.expires_at == self.future_time
293307
mock_get_or_create.assert_called_once_with(member=self.member)
294308
mock_save.assert_called_once()
295309
mock_flow_instance.fetch_token.assert_called_once_with(authorization_response={})
310+
mock_get_kms_client.return_value.encrypt.assert_any_call(b"token")
311+
mock_get_kms_client.return_value.encrypt.assert_any_call(b"refresh_token")
296312

297313
@override_settings(
298314
IS_GOOGLE_AUTH_ENABLED=True,
315+
IS_AWS_KMS_ENABLED=True,
299316
GOOGLE_AUTH_CLIENT_ID="test_client_id",
300317
GOOGLE_AUTH_CLIENT_SECRET="test_client_secret", # noqa: S106
301318
GOOGLE_AUTH_REDIRECT_URI="http://localhost:8000/callback",
@@ -306,3 +323,49 @@ def test_authenticate_callback_member_not_found(self, mock_member_get):
306323
mock_member_get.side_effect = Member.DoesNotExist
307324
with pytest.raises(ValidationError, match="Member with Slack ID 4 does not exist."):
308325
GoogleAuth.authenticate_callback(auth_response={}, member_id=4)
326+
327+
@override_settings(
328+
IS_GOOGLE_AUTH_ENABLED=True,
329+
IS_AWS_KMS_ENABLED=True,
330+
GOOGLE_AUTH_CLIENT_ID="test_client_id",
331+
GOOGLE_AUTH_CLIENT_SECRET="test_client_secret", # noqa: S106
332+
GOOGLE_AUTH_REDIRECT_URI="http://localhost:8000/callback",
333+
)
334+
@patch("apps.slack.models.google_auth.GoogleAuth.get_kms_client")
335+
def test_return_decrypted_access_token(self, mock_get_kms_client):
336+
"""Test return_decrypted_access_token returns decrypted token."""
337+
auth = GoogleAuth(
338+
member=self.member,
339+
access_token=b"encrypted_token",
340+
refresh_token=b"encrypted_token",
341+
expires_at=self.future_time,
342+
)
343+
mock_get_kms_client.return_value.decrypt.return_value = "decrypted_token"
344+
result = auth.access_token_str
345+
assert result == "decrypted_token"
346+
347+
@override_settings(
348+
IS_GOOGLE_AUTH_ENABLED=True,
349+
IS_AWS_KMS_ENABLED=True,
350+
GOOGLE_AUTH_CLIENT_ID="test_client_id",
351+
GOOGLE_AUTH_CLIENT_SECRET="test_client_secret", # noqa: S106
352+
GOOGLE_AUTH_REDIRECT_URI="http://localhost:8000/callback",
353+
)
354+
@patch("apps.slack.models.google_auth.GoogleAuth.get_kms_client")
355+
def test_return_decrypted_refresh_token(self, mock_get_kms_client):
356+
"""Test return_decrypted_refresh_token returns decrypted token."""
357+
auth = GoogleAuth(
358+
member=self.member,
359+
access_token=b"encrypted_token",
360+
refresh_token=b"encrypted_token",
361+
expires_at=self.future_time,
362+
)
363+
mock_get_kms_client.return_value.decrypt.return_value = "decrypted_token"
364+
result = auth.refresh_token_str
365+
assert result == "decrypted_token"
366+
367+
@override_settings(IS_AWS_KMS_ENABLED=False)
368+
def test_get_kms_client_error(self):
369+
"""Test get_kms_client raises error when KMS is disabled."""
370+
with pytest.raises(ValueError, match="AWS KMS is not enabled."):
371+
GoogleAuth.get_kms_client()

0 commit comments

Comments
 (0)