Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/githubapp/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from .session import SessionManager
from contextlib import asynccontextmanager


LOG = logging.getLogger(__name__)

STATUS_FUNC_CALLED = "HIT"
Expand Down
86 changes: 27 additions & 59 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import pytest
import json
import time
from unittest.mock import patch, Mock, mock_open
from fastapi import APIRouter, Request, FastAPI
from unittest.mock import patch, Mock
from fastapi import FastAPI
from fastapi.testclient import TestClient
from githubapp import GitHubApp
from githubapp.core import (
Expand Down Expand Up @@ -352,38 +351,27 @@ def test_client_with_payload_installation(self, mock_ghapi, mock_get_token):

github_app = GitHubApp()
github_app.payload = {"installation": {"id": 456}}
result = github_app.client()
github_app.client()

mock_get_token.assert_called_once_with(456)


class TestGitHubAppWebhookHandling:
def test_extract_payload_valid_json(self):
app = FastAPI()
github_app = GitHubApp(app)
github_app.init_app(app)

with TestClient(app) as client:
# simplified; no real assertion here
pass

def test_handle_request_missing_content_type(self):
app = FastAPI()
github_app = GitHubApp(app)
github_app.init_app(app)
GitHubApp(app)

with TestClient(app) as client:
response = client.post("/", json={"test": "data"})
response = client.post("/webhooks/github/", json={"test": "data"})
assert response.status_code == 400

def test_handle_request_missing_github_event_header(self):
app = FastAPI()
github_app = GitHubApp(app)
github_app.init_app(app)
GitHubApp(app)

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={"installation": {"id": 123}},
headers={"Content-Type": "application/json"},
)
Expand All @@ -395,17 +383,16 @@ def test_handle_request_valid_webhook(self):
app,
github_app_id=123,
github_app_key=b"test_key",
github_app_secret=False, # Disable signature verification for testing
github_app_secret=False,
)
github_app.init_app(app)

@github_app.on("issues.opened")
def test_handler():
return "handled"

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={
"action": "opened",
"installation": {"id": 123},
Expand All @@ -427,17 +414,16 @@ def test_handle_request_call_async_hook_function(self):
app,
github_app_id=123,
github_app_key=b"test_key",
github_app_secret=False, # Disable signature verification for testing
github_app_secret=False,
)
github_app.init_app(app)

@github_app.on("issues.opened")
async def async_test_handler():
return "handled"

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={
"action": "opened",
"installation": {"id": 123},
Expand All @@ -454,38 +440,16 @@ async def async_test_handler():
assert "async_test_handler" in data["calls"]


class TestGitHubAppWebhookSignatureVerification:
def test_signature_verification_disabled(self):
app = FastAPI()
github_app = GitHubApp(
app, github_app_secret=False # Explicitly disable verification
)
# Test that webhooks work without signature headers when verification is disabled

def test_signature_verification_sha256_valid(self):
app = FastAPI()
github_app = GitHubApp(app, github_app_secret=b"test_secret")
# Test that valid SHA256 signatures are accepted

def test_signature_verification_sha256_invalid(self):
app = FastAPI()
github_app = GitHubApp(app, github_app_secret=b"test_secret")
# Test that invalid SHA256 signatures are rejected

def test_signature_verification_sha1_fallback(self):
app = FastAPI()
github_app = GitHubApp(app, github_app_secret=b"test_secret")
# Test that SHA1 signatures work when SHA256 is not present


class TestGitHubAppIntegration:
def test_full_webhook_flow(self):
"""Test complete webhook handling flow"""
app = FastAPI()
github_app = GitHubApp(
app, github_app_id=123, github_app_key=b"test_key", github_app_secret=False
app,
github_app_id=123,
github_app_key=b"test_key",
github_app_secret=False,
)
github_app.init_app(app)

results = []

Expand All @@ -501,7 +465,7 @@ def handle_opened_issue():

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={
"action": "opened",
"installation": {"id": 123},
Expand All @@ -523,14 +487,16 @@ def handle_opened_issue():
def test_no_matching_handlers(self):
"""Test webhook with no matching handlers"""
app = FastAPI()
github_app = GitHubApp(
app, github_app_id=123, github_app_key=b"test_key", github_app_secret=False
GitHubApp(
app,
github_app_id=123,
github_app_key=b"test_key",
github_app_secret=False,
)
github_app.init_app(app)

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={
"action": "closed",
"installation": {"id": 123},
Expand All @@ -551,17 +517,19 @@ def test_handler_exception_returns_500(self):
"""Test that exceptions in handlers return 500"""
app = FastAPI()
github_app = GitHubApp(
app, github_app_id=123, github_app_key=b"test_key", github_app_secret=False
app,
github_app_id=123,
github_app_key=b"test_key",
github_app_secret=False,
)
github_app.init_app(app)

@github_app.on("issues.opened")
def failing_handler():
raise ValueError("Something went wrong")

with TestClient(app) as client:
response = client.post(
"/",
"/webhooks/github/",
json={
"action": "opened",
"installation": {"id": 123},
Expand Down
1 change: 0 additions & 1 deletion tests/test_oauth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
from urllib.parse import urlparse, parse_qs

import pytest
Expand Down
4 changes: 2 additions & 2 deletions tests/test_rate_limiting.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from unittest.mock import Mock, patch, MagicMock
from unittest.mock import Mock, patch
import time
from githubapp import GitHubApp, with_rate_limit_handling

Expand Down Expand Up @@ -133,7 +133,7 @@ def test_get_client_alias(self):
client2 = self.app.get_client(123)

# Both should return the same type of object
assert type(client1) == type(client2)
assert client1.__class__ is client2.__class__

def test_decorator_restores_original_methods(self):
"""Test that the decorator properly restores original methods after execution."""
Expand Down
Loading