diff --git a/test_mcp_changes.sh b/test_mcp_changes.sh deleted file mode 100644 index d905ac3..0000000 --- a/test_mcp_changes.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# Test script to verify MCP server organization member support - -set -e - -echo "Testing MCP Server Organization Member Support" -echo "==============================================" -echo "" - -# Test 1: Create individual member -echo "Test 1: Creating individual member..." -INDIVIDUAL_RESULT=$(echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "create_member", "arguments": {"firstName": "Bob", "lastName": "Jones", "email": "bob@example.com"}}}' | node dist/mcp_server.js 2>/dev/null | tail -n 1) -echo "✓ Individual member created" -echo "" - -# Test 2: Create organization member -echo "Test 2: Creating organization member..." -ORG_RESULT=$(echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "create_member", "arguments": {"memberType": "ORGANIZATION", "companyName": "Acme Corp", "email": "info@acme.com"}}}' | node dist/mcp_server.js 2>/dev/null | tail -n 1) -echo "✓ Organization member created" -echo "" - -# Test 3: List members -echo "Test 3: Listing all members..." -LIST_RESULT=$(echo '{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "list_members", "arguments": {}}}' | node dist/mcp_server.js 2>/dev/null | tail -n 1) -echo "✓ Members listed" -echo "" - -# Test 4: Get GraphQL schema -echo "Test 4: Checking GraphQL schema for MemberType enum..." -SCHEMA_RESULT=$(echo '{"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "get_graphql_schema", "arguments": {}}}' | node dist/mcp_server.js 2>/dev/null | tail -n 1) -if echo "$SCHEMA_RESULT" | grep -q "MemberType"; then - echo "✓ MemberType enum found in schema" -else - echo "✗ MemberType enum NOT found in schema" - exit 1 -fi -echo "" - -echo "All tests passed!" diff --git a/test_organization_members.py b/test_organization_members.py deleted file mode 100755 index 3e60b4f..0000000 --- a/test_organization_members.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -"""Test script for organization member support via GraphQL API.""" - -import httpx -import json - -API_URL = "http://127.0.0.1:8000/graphql" - -def execute_query(query: str, variables: dict = None): - """Execute a GraphQL query.""" - payload = {"query": query} - if variables: - payload["variables"] = variables - - response = httpx.post(API_URL, json=payload) - response.raise_for_status() - result = response.json() - - if "errors" in result: - print(f"GraphQL Errors: {result['errors']}") - raise Exception(f"GraphQL query failed: {result['errors']}") - - return result["data"] - -# Test 1: Create individual member -print("Test 1: Creating individual member...") -create_individual_query = """ -mutation CreateMember($input: CreateMemberInput!) { - createMember(input: $input) { - id - memberType - firstName - lastName - companyName - } -} -""" -individual_result = execute_query(create_individual_query, { - "input": { - "firstName": "Charlie", - "lastName": "Brown", - "email": "charlie@example.com" - } -}) -print(f"✓ Created individual member: {individual_result['createMember']}") -assert individual_result['createMember']['memberType'] == 'INDIVIDUAL' -assert individual_result['createMember']['firstName'] == 'Charlie' -assert individual_result['createMember']['companyName'] is None -print() - -# Test 2: Create organization member -print("Test 2: Creating organization member...") -create_org_query = """ -mutation CreateMember($input: CreateMemberInput!) { - createMember(input: $input) { - id - memberType - firstName - companyName - } -} -""" -org_result = execute_query(create_org_query, { - "input": { - "memberType": "ORGANIZATION", - "companyName": "Tech Innovations Inc", - "email": "info@techinnovations.com" - } -}) -print(f"✓ Created organization member: {org_result['createMember']}") -assert org_result['createMember']['memberType'] == 'ORGANIZATION' -assert org_result['createMember']['companyName'] == 'Tech Innovations Inc' -print() - -# Test 3: Create organization with contact person -print("Test 3: Creating organization with contact person...") -org_with_contact_result = execute_query(create_org_query, { - "input": { - "memberType": "ORGANIZATION", - "companyName": "Global Solutions Ltd", - "firstName": "Jane", - "lastName": "Doe", - "email": "contact@globalsolutions.com" - } -}) -print(f"✓ Created organization with contact: {org_with_contact_result['createMember']}") -assert org_with_contact_result['createMember']['memberType'] == 'ORGANIZATION' -assert org_with_contact_result['createMember']['companyName'] == 'Global Solutions Ltd' -assert org_with_contact_result['createMember']['firstName'] == 'Jane' -print() - -# Test 4: List all members -print("Test 4: Listing all members...") -list_query = """ -query { - members { - id - memberType - firstName - lastName - companyName - } -} -""" -list_result = execute_query(list_query) -members = list_result['members'] -print(f"✓ Found {len(members)} members") -print(" Members:") -for member in members: - if member['memberType'] == 'INDIVIDUAL': - print(f" - Individual: {member['firstName']} {member['lastName']}") - else: - print(f" - Organization: {member['companyName']}") -print() - -# Test 5: Verify validation - individual without firstName should fail -print("Test 5: Testing validation - individual without firstName (should fail)...") -try: - execute_query(create_individual_query, { - "input": { - "memberType": "INDIVIDUAL", - "email": "nofirstname@example.com" - } - }) - print("✗ Should have failed but didn't!") - exit(1) -except Exception as e: - print(f"✓ Correctly rejected: {str(e)[:100]}") -print() - -# Test 6: Verify validation - organization without companyName should fail -print("Test 6: Testing validation - organization without companyName (should fail)...") -try: - execute_query(create_org_query, { - "input": { - "memberType": "ORGANIZATION", - "email": "nocompany@example.com" - } - }) - print("✗ Should have failed but didn't!") - exit(1) -except Exception as e: - print(f"✓ Correctly rejected: {str(e)[:100]}") -print() - -# Test 7: Check introspection for MemberType enum -print("Test 7: Verifying MemberType enum in schema...") -introspection_query = """ -query { - __type(name: "MemberType") { - name - kind - enumValues { - name - } - } -} -""" -introspection_result = execute_query(introspection_query) -member_type_enum = introspection_result['__type'] -print(f"✓ Found MemberType enum: {member_type_enum['name']}") -enum_values = [ev['name'] for ev in member_type_enum['enumValues']] -print(f" Enum values: {enum_values}") -assert 'INDIVIDUAL' in enum_values -assert 'ORGANIZATION' in enum_values -print() - -print("=" * 50) -print("All tests passed! ✓") -print("=" * 50) diff --git a/tests/e2e/test_graphql_api.py b/tests/e2e/test_graphql_api.py index 2ea8df4..62b165b 100644 --- a/tests/e2e/test_graphql_api.py +++ b/tests/e2e/test_graphql_api.py @@ -153,3 +153,31 @@ class TestGraphQLAPI: # The error should mention validation error_message = str(data["errors"]) assert "Invalid email format" in error_message or "email" in error_message.lower() + + async def test_introspect_member_type_enum(self, graphql_client): + """Test GraphQL introspection returns MemberType enum.""" + query = """ + query { + __type(name: "MemberType") { + name + kind + enumValues { + name + } + } + } + """ + + response = await graphql_client.post("/graphql", json={"query": query}) + assert response.status_code == 200 + + data = response.json() + assert "data" in data + + member_type = data["data"]["__type"] + assert member_type["name"] == "MemberType" + assert member_type["kind"] == "ENUM" + + enum_values = {ev["name"] for ev in member_type["enumValues"]} + assert "INDIVIDUAL" in enum_values + assert "ORGANIZATION" in enum_values diff --git a/tests/integration/test_member_mutations.py b/tests/integration/test_member_mutations.py index 527883e..d1b5514 100644 --- a/tests/integration/test_member_mutations.py +++ b/tests/integration/test_member_mutations.py @@ -3,9 +3,9 @@ import pytest from sqlalchemy import select -from src.models.member import Member +from src.models.member import Member, MemberType from src.resolvers.member import MemberNotFoundError, Mutation -from src.schemas.member import CreateMemberInput, UpdateMemberInput +from src.schemas.member import CreateMemberInput, MemberType as SchemaMemberType, UpdateMemberInput from src.validation import ValidationError @@ -89,6 +89,57 @@ class TestCreateMemberMutation: with pytest.raises(ValidationError, match="firstName is required for individual members"): await mutation.create_member(input=input_data) + async def test_create_organization_member(self, async_session, patched_session_maker): + """Test creating an organization member with companyName.""" + mutation = Mutation() + input_data = CreateMemberInput( + member_type=SchemaMemberType.ORGANIZATION, + company_name="Tech Innovations Inc", + email="info@techinnovations.com" + ) + + result = await mutation.create_member(input=input_data) + + assert result.id is not None + assert result.member_type == SchemaMemberType.ORGANIZATION + assert result.company_name == "Tech Innovations Inc" + assert result.first_name is None + + # Verify in database + db_result = await async_session.execute( + select(Member).where(Member.id == result.id) + ) + db_member = db_result.scalar_one() + assert db_member.member_type.value == "ORGANIZATION" + assert db_member.company_name == "Tech Innovations Inc" + + async def test_create_organization_with_contact_person(self, async_session, patched_session_maker): + """Test creating an organization with contact person.""" + mutation = Mutation() + input_data = CreateMemberInput( + member_type=SchemaMemberType.ORGANIZATION, + company_name="Global Solutions Ltd", + first_name="Jane", + last_name="Doe", + email="contact@globalsolutions.com" + ) + + result = await mutation.create_member(input=input_data) + + assert result.member_type == SchemaMemberType.ORGANIZATION + assert result.company_name == "Global Solutions Ltd" + assert result.first_name == "Jane" + assert result.last_name == "Doe" + + # Verify in database + db_result = await async_session.execute( + select(Member).where(Member.id == result.id) + ) + db_member = db_result.scalar_one() + assert db_member.member_type.value == "ORGANIZATION" + assert db_member.company_name == "Global Solutions Ltd" + assert db_member.first_name == "Jane" + class TestUpdateMemberMutation: """Tests for updateMember mutation.""" diff --git a/tests/integration/test_member_queries.py b/tests/integration/test_member_queries.py index e8f3293..1f575ef 100644 --- a/tests/integration/test_member_queries.py +++ b/tests/integration/test_member_queries.py @@ -3,7 +3,7 @@ import pytest from sqlalchemy import select -from src.models.member import Member +from src.models.member import Member, MemberType from src.resolvers.member import Query @@ -92,3 +92,40 @@ class TestMemberQueries: assert results[2].last_name is None assert results[3].first_name == "Bob" assert results[3].last_name is None + + async def test_query_mixed_member_types(self, async_session, patched_session_maker): + """Test querying returns both individual and organization members.""" + # Create individual member + individual = Member( + member_type=MemberType.INDIVIDUAL, + first_name="Alice", + last_name="Smith" + ) + async_session.add(individual) + + # Create organization member + organization = Member( + member_type=MemberType.ORGANIZATION, + company_name="Acme Corp", + email="info@acme.com" + ) + async_session.add(organization) + await async_session.commit() + + # Query all members + query = Query() + result = await query.members() + + assert len(result) == 2 + types = {m.member_type for m in result} + assert MemberType.INDIVIDUAL in types + assert MemberType.ORGANIZATION in types + + # Verify individual member data + individual_result = next(m for m in result if m.member_type == MemberType.INDIVIDUAL) + assert individual_result.first_name == "Alice" + assert individual_result.last_name == "Smith" + + # Verify organization member data + org_result = next(m for m in result if m.member_type == MemberType.ORGANIZATION) + assert org_result.company_name == "Acme Corp"