Skip to content

Commit 7b94ffa

Browse files
authored
Merge pull request #16 from geekbot-com/fix/confidential-parsing
Support confidential standups
2 parents ce21e53 + 58018f5 commit 7b94ffa

File tree

3 files changed

+234
-4
lines changed

3 files changed

+234
-4
lines changed

geekbot_mcp/models.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Standup(BaseModel):
4040

4141
id: int
4242
name: str
43-
channel: str
43+
channel: str | None
4444
time: str
4545
timezone: str
4646
questions: list[Question]
@@ -136,10 +136,14 @@ def poll_question_from_json_response(q_res: dict) -> Question:
136136

137137

138138
def standup_from_json_response(s_res: dict) -> Standup:
139+
channel = s_res["channel"]
140+
if not channel:
141+
channel = "confidential standup - dm with user"
142+
139143
return Standup(
140144
id=s_res["id"],
141145
name=s_res["name"],
142-
channel=s_res["channel"],
146+
channel=channel,
143147
time=s_res["time"],
144148
timezone=s_res["timezone"],
145149
questions=[question_from_json_response(q) for q in s_res["questions"]],

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "geekbot-mcp"
7-
version = "0.3.0"
7+
version = "0.3.1"
88
description = "Model Context Protocol (MCP) server integrating Geekbot data and tools to Claude AI"
99
readme = "README.md"
1010
requires-python = ">=3.10"

tests/test_models.py

Lines changed: 227 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
PollQuestionResults,
99
PollResults,
1010
Report,
11+
Standup,
1112
User,
1213
poll_results_from_json_response,
1314
posted_report_from_json_response,
15+
standup_from_json_response,
1416
)
1517

1618
SAMPLE_POLL_RESULT_JSON = """
@@ -284,7 +286,7 @@
284286
},
285287
{
286288
"id": 3386416,
287-
"name": "sabtestpoll",
289+
"name": "testpoll",
288290
"time": "18:23:32",
289291
"timezone": "Europe/Athens",
290292
"questions": [
@@ -391,6 +393,202 @@
391393
}
392394
"""
393395

396+
STANDUPS_LIST = """
397+
[
398+
{
399+
"id": 1942323270,
400+
"name": "testconfidential",
401+
"time": "16:00:00",
402+
"wait_time": -1,
403+
"timezone": "user_local",
404+
"days": [],
405+
"channel": null,
406+
"channel_ready": true,
407+
"questions": [
408+
{
409+
"id": 57508,
410+
"color": "E5C1F5",
411+
"text": "Was anything a particular struggle?",
412+
"schedule": null,
413+
"answer_type": "text",
414+
"answer_choices": [],
415+
"hasAnswers": false,
416+
"is_random": false,
417+
"random_texts": [],
418+
"prefilled_by": null,
419+
"text_id": 523,
420+
"preconditions": [],
421+
"label": "other"
422+
},
423+
{
424+
"id": 506,
425+
"color": "EEEEEE",
426+
"text": "If there was one thing I could do to help you, what would it be?",
427+
"schedule": null,
428+
"answer_type": "text",
429+
"answer_choices": [],
430+
"hasAnswers": false,
431+
"is_random": false,
432+
"random_texts": [],
433+
"prefilled_by": null,
434+
"text_id": 527,
435+
"preconditions": [],
436+
"label": "other"
437+
},
438+
{
439+
"id": 6157509,
440+
"color": "CEF1F3",
441+
"text": "On a scale of 1-10, how happy are you with your work-life balance?",
442+
"schedule": null,
443+
"answer_type": "numeric",
444+
"answer_choices": [],
445+
"hasAnswers": false,
446+
"is_random": false,
447+
"random_texts": [],
448+
"prefilled_by": null,
449+
"text_id": 121528,
450+
"preconditions": [],
451+
"label": "other"
452+
},
453+
{
454+
"id": 57510,
455+
"color": "FBDADD",
456+
"text": "Growth-wise, where do you want to focus next month?",
457+
"schedule": null,
458+
"answer_type": "text",
459+
"answer_choices": [],
460+
"hasAnswers": false,
461+
"is_random": false,
462+
"random_texts": [],
463+
"prefilled_by": null,
464+
"text_id": 121530,
465+
"preconditions": [],
466+
"label": "other"
467+
},
468+
{
469+
"id": 57507,
470+
"color": "E5C1F5",
471+
"text": "Anything you'd like to add?",
472+
"schedule": null,
473+
"answer_type": "text",
474+
"answer_choices": [],
475+
"hasAnswers": false,
476+
"is_random": false,
477+
"random_texts": [],
478+
"prefilled_by": null,
479+
"text_id": 20887,
480+
"preconditions": [],
481+
"label": "other"
482+
}
483+
],
484+
"users": [
485+
{
486+
"id": "U02PV",
487+
"role": "billing_admin",
488+
"email": "[email protected]",
489+
"username": "myfriend",
490+
"realname": "My Friend",
491+
"profile_img": "https://secure.gravatar.com/my-friend.png"
492+
}
493+
],
494+
"users_total": 1,
495+
"webhooks": [],
496+
"master": "UBTDMUC34W",
497+
"sync_channel_members": false,
498+
"sync_channel_ready": false,
499+
"sync_channel": null
500+
},
501+
{
502+
"id": 3221,
503+
"name": "teststandup",
504+
"time": "10:00:00",
505+
"wait_time": -1,
506+
"timezone": "user_local",
507+
"days": [],
508+
"channel": "--test",
509+
"channel_ready": true,
510+
"questions": [
511+
{
512+
"id": 977,
513+
"color": "EEEEEE",
514+
"text": "How do you feel today?",
515+
"schedule": null,
516+
"answer_type": "text",
517+
"answer_choices": [],
518+
"hasAnswers": true,
519+
"is_random": false,
520+
"random_texts": [],
521+
"prefilled_by": null,
522+
"text_id": 20725,
523+
"preconditions": [],
524+
"label": "sentiment"
525+
},
526+
{
527+
"id": 980,
528+
"color": "CEF1F3",
529+
"text": "What have you done since {last_report_date}?",
530+
"schedule": null,
531+
"answer_type": "text",
532+
"answer_choices": [],
533+
"hasAnswers": true,
534+
"is_random": false,
535+
"random_texts": [],
536+
"prefilled_by": 43978,
537+
"text_id": 439,
538+
"preconditions": [],
539+
"label": "done"
540+
},
541+
{
542+
"id": 3978,
543+
"color": "D299EB",
544+
"text": "What will you do today?",
545+
"schedule": null,
546+
"answer_type": "text",
547+
"answer_choices": [],
548+
"hasAnswers": true,
549+
"is_random": false,
550+
"random_texts": [],
551+
"prefilled_by": null,
552+
"text_id": 20197,
553+
"preconditions": [],
554+
"label": "todo"
555+
},
556+
{
557+
"id": 3979,
558+
"color": "FBDADD",
559+
"text": "Anything blocking your progress?",
560+
"schedule": null,
561+
"answer_type": "text",
562+
"answer_choices": [],
563+
"hasAnswers": true,
564+
"is_random": false,
565+
"random_texts": [],
566+
"prefilled_by": null,
567+
"text_id": 20868,
568+
"preconditions": [],
569+
"label": "obstacles"
570+
}
571+
],
572+
"users": [
573+
{
574+
"id": "UBTDMUC34W",
575+
"role": "member",
576+
"email": "[email protected]",
577+
"username": "jd",
578+
"realname": "John Doe",
579+
"profile_img": "https://avatars.slack-edge.com/jd-avatar.png"
580+
}
581+
],
582+
"users_total": 1,
583+
"webhooks": [],
584+
"master": "UBTDMUC34W",
585+
"sync_channel_members": false,
586+
"sync_channel_ready": false,
587+
"sync_channel": null
588+
}
589+
]
590+
"""
591+
394592

395593
@pytest.fixture
396594
def sample_poll_result_data() -> dict:
@@ -416,6 +614,12 @@ def posted_report_data() -> dict:
416614
return json.loads(POSTED_REPORT_JSON)
417615

418616

617+
@pytest.fixture
618+
def standups_list() -> list[dict]:
619+
"""Provides the standups list as a list of dictionaries."""
620+
return json.loads(STANDUPS_LIST)
621+
622+
419623
def test_poll_results_parsing(sample_poll_result_data: dict):
420624
"""Tests parsing of sample poll results JSON into a PollResults object."""
421625
parsed_result = poll_results_from_json_response(sample_poll_result_data)
@@ -496,3 +700,25 @@ def test_posted_report_parsing(posted_report_data: dict):
496700
assert parsed_result.reporter.id == "UBTDMUC34W"
497701
assert parsed_result.reporter.name == "John Doe"
498702
assert parsed_result.reporter.username == "jd"
703+
704+
705+
def test_standups_list_parsing(standups_list: list[dict]):
706+
"""Tests parsing of standups list JSON into a StandupsList object."""
707+
standup = standups_list[1]
708+
parsed_result = standup_from_json_response(standup)
709+
710+
assert isinstance(parsed_result, Standup)
711+
assert parsed_result.id == standup["id"]
712+
assert parsed_result.name == standup["name"]
713+
assert parsed_result.channel == standup["channel"]
714+
assert parsed_result.time == standup["time"]
715+
assert parsed_result.timezone == standup["timezone"]
716+
717+
confidential_standup = standups_list[0]
718+
parsed_result = standup_from_json_response(confidential_standup)
719+
720+
assert isinstance(parsed_result, Standup)
721+
assert parsed_result.channel == "confidential standup - dm with user"
722+
assert parsed_result.name == confidential_standup["name"]
723+
assert parsed_result.time == confidential_standup["time"]
724+
assert parsed_result.timezone == confidential_standup["timezone"]

0 commit comments

Comments
 (0)