Skip to content

Commit 7c033a2

Browse files
committed
fix: qa
1 parent 5461303 commit 7c033a2

4 files changed

Lines changed: 44 additions & 14 deletions

File tree

backend/openedx_ai_badges/workflows/orchestrators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,6 @@ def generate_image(self, input_data):
512512
"response": badge_image_data,
513513
"status": "completed",
514514
}
515-
except Exception as e:
515+
except Exception as e: # pylint: disable=broad-exception-caught
516516
logger.error("Image generation failed: %s", str(e))
517517
return {'error': f"Image generation failed: {str(e)}", 'status': 'error'}

backend/tests/test_mit_dcc_orchestrator.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,29 @@ def test_get_api_status_ollama_starting_when_models_list_empty(mock_settings, mo
1616
badge_resp = MagicMock(ok=True)
1717
ollama_resp = MagicMock(ok=True)
1818
ollama_resp.json.return_value = {"models": []}
19-
mock_get.side_effect = [badge_resp, ollama_resp]
19+
image_resp = MagicMock(ok=True)
20+
21+
def side_effect(url, **kwargs):
22+
if "api/tags" in url:
23+
return ollama_resp
24+
if "badge.example" in url:
25+
return badge_resp
26+
if "image.example" in url:
27+
return image_resp
28+
return MagicMock(ok=False)
29+
30+
mock_get.side_effect = side_effect
2031

2132
mock_settings.MIT_DCC_BADGE_API_HEALTH_URL = "https://badge.example/health"
2233
mock_settings.MIT_SLM_OLLAMA_URL = "https://ollama.example/api/generate"
2334
mock_settings.MIT_SLM_OLLAMA_TOKEN = "secret"
35+
mock_settings.MIT_DCC_BADGE_IMAGE_API_HEALTH_URL = "https://image.example/health"
2436

2537
result = _orchestrator().get_api_status({})
2638

2739
assert result["services"]["badge_api"]["status"] == "online"
2840
assert result["services"]["ollama"]["status"] == "starting"
41+
assert result["services"]["image_api"]["status"] == "online"
2942

3043

3144
@patch("openedx_ai_badges.workflows.orchestrators.requests.get")
@@ -35,16 +48,29 @@ def test_get_api_status_ollama_online_when_models_list_has_entries(mock_settings
3548
badge_resp = MagicMock(ok=True)
3649
ollama_resp = MagicMock(ok=True)
3750
ollama_resp.json.return_value = {"models": [{"name": "phi4-chat:latest"}]}
38-
mock_get.side_effect = [badge_resp, ollama_resp]
51+
image_resp = MagicMock(ok=True)
52+
53+
def side_effect(url, **kwargs):
54+
if "api/tags" in url:
55+
return ollama_resp
56+
if "badge.example" in url:
57+
return badge_resp
58+
if "image.example" in url:
59+
return image_resp
60+
return MagicMock(ok=False)
61+
62+
mock_get.side_effect = side_effect
3963

4064
mock_settings.MIT_DCC_BADGE_API_HEALTH_URL = "https://badge.example/health"
4165
mock_settings.MIT_SLM_OLLAMA_URL = "https://ollama.example/api/generate"
4266
mock_settings.MIT_SLM_OLLAMA_TOKEN = "secret"
67+
mock_settings.MIT_DCC_BADGE_IMAGE_API_HEALTH_URL = "https://image.example/health"
4368

4469
result = _orchestrator().get_api_status({})
4570

4671
assert result["services"]["badge_api"]["status"] == "online"
4772
assert result["services"]["ollama"]["status"] == "online"
73+
assert result["services"]["image_api"]["status"] == "online"
4874

4975

5076
@patch("openedx_ai_badges.workflows.orchestrators.requests.post")
@@ -55,17 +81,19 @@ def test_generate_image_success(mock_settings, mock_post):
5581

5682
# Mock response
5783
mock_resp = MagicMock(ok=True)
58-
mock_resp.json.return_value = {"base64": "fakebase64", "config": {"layers": []}}
84+
mock_resp.json.return_value = {
85+
"data": {"base64": "fakebase64"},
86+
"config": {"layers": []}
87+
}
5988
mock_post.return_value = mock_resp
6089

6190
# Mock orchestrator and session
62-
orchestrator = MITDCCBadgeOrchestrator(
63-
profile=MagicMock(),
64-
session=MagicMock(metadata={"complete_info": {"badge": {"name": "Test"}}}),
65-
location_id="loc",
66-
course_id="course",
67-
user=MagicMock()
68-
)
91+
orchestrator = object.__new__(MITDCCBadgeOrchestrator)
92+
orchestrator.profile = MagicMock()
93+
orchestrator.session = MagicMock(metadata={"complete_info": {"badge": {"name": "Test"}}})
94+
orchestrator.location_id = "loc"
95+
orchestrator.course_id = "course"
96+
orchestrator.user = MagicMock()
6997

7098
result = orchestrator.generate_image({
7199
"mode": "icon_based",

frontend/src/components/AIBadgesTab/BadgePreview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ const BadgePreview = ({
9393
{generatedBadge.badgeImage ? (
9494
<div className="mb-4">
9595
<img
96-
src={generatedBadge.badgeImage.base64.startsWith('data:')
97-
? generatedBadge.badgeImage.base64
96+
src={generatedBadge.badgeImage.base64.startsWith('data:')
97+
? generatedBadge.badgeImage.base64
9898
: `data:image/png;base64,${generatedBadge.badgeImage.base64}`}
9999
alt="Generated Badge"
100100
style={{ maxWidth: '300px', height: 'auto' }}

frontend/src/hooks/useBadgeGeneration.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
BadgeSectionKey,
99
BadgeWorkflowAction,
1010
ProfileConfig,
11+
BadgeImageResult,
1112
} from '../types/badges';
1213

1314
const POLL_INTERVAL_MS = 5000;
@@ -252,7 +253,8 @@ export const useBadgeGeneration = (
252253
} else if (result.status === 'completed' && result.response) {
253254
// The result contains {base64, config}
254255
// We update the local state with the new badge image
255-
setGeneratedBadge((prev) => (prev ? { ...prev, badgeImage: result.response } : prev));
256+
const badgeImage = result.response as BadgeImageResult;
257+
setGeneratedBadge((prev) => (prev ? { ...prev, badgeImage } : prev));
256258
}
257259
} catch (error: unknown) {
258260
setGenerationError(error instanceof Error ? error.message : 'An unexpected error occurred');

0 commit comments

Comments
 (0)