mockforge_graphql/
schema.rs

1//! GraphQL schema parsing and generation
2
3use async_graphql::{EmptyMutation, EmptySubscription, Object, Schema};
4
5/// Simple User type for GraphQL
6#[derive(async_graphql::SimpleObject, Clone)]
7pub struct User {
8    /// Unique identifier
9    pub id: String,
10    /// User's full name
11    pub name: String,
12    /// User's email address
13    pub email: String,
14}
15
16/// Simple Post type for GraphQL
17#[derive(async_graphql::SimpleObject)]
18pub struct Post {
19    /// Unique identifier
20    pub id: String,
21    /// Post title
22    pub title: String,
23    /// Post content
24    pub content: String,
25    /// Author of the post
26    pub author: User,
27}
28
29/// Root query type
30pub struct QueryRoot;
31
32#[Object]
33impl QueryRoot {
34    /// Get all users
35    async fn users(&self, limit: Option<i32>) -> Vec<User> {
36        let limit = limit.unwrap_or(10) as usize;
37        (0..limit.min(100))
38            .map(|i| User {
39                id: format!("user-{}", i),
40                name: format!("User {}", i),
41                email: format!("user{}@example.com", i),
42            })
43            .collect()
44    }
45
46    /// Get a user by ID
47    async fn user(&self, id: String) -> Option<User> {
48        Some(User {
49            id,
50            name: "Mock User".to_string(),
51            email: "mock@example.com".to_string(),
52        })
53    }
54
55    /// Get all posts
56    async fn posts(&self, limit: Option<i32>) -> Vec<Post> {
57        let limit = limit.unwrap_or(10) as usize;
58        (0..limit.min(50))
59            .map(|i| Post {
60                id: format!("post-{}", i),
61                title: format!("Post {}", i),
62                content: format!("This is the content of post {}", i),
63                author: User {
64                    id: format!("user-{}", i % 5),
65                    name: format!("Author {}", i % 5),
66                    email: format!("author{}@example.com", i % 5),
67                },
68            })
69            .collect()
70    }
71}
72
73/// GraphQL schema manager
74pub struct GraphQLSchema {
75    schema: Schema<QueryRoot, EmptyMutation, EmptySubscription>,
76}
77
78impl GraphQLSchema {
79    /// Create a new basic schema
80    pub fn new() -> Self {
81        let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish();
82        Self { schema }
83    }
84
85    /// Get the underlying schema
86    pub fn schema(&self) -> &Schema<QueryRoot, EmptyMutation, EmptySubscription> {
87        &self.schema
88    }
89
90    /// Generate a basic schema with common types
91    pub fn generate_basic_schema() -> Self {
92        Self::new()
93    }
94}
95
96impl Default for GraphQLSchema {
97    fn default() -> Self {
98        Self::new()
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn test_user_creation() {
108        let user = User {
109            id: "user-1".to_string(),
110            name: "John Doe".to_string(),
111            email: "john@example.com".to_string(),
112        };
113
114        assert_eq!(user.id, "user-1");
115        assert_eq!(user.name, "John Doe");
116        assert_eq!(user.email, "john@example.com");
117    }
118
119    #[test]
120    fn test_post_creation() {
121        let user = User {
122            id: "user-1".to_string(),
123            name: "Author".to_string(),
124            email: "author@example.com".to_string(),
125        };
126
127        let post = Post {
128            id: "post-1".to_string(),
129            title: "Test Post".to_string(),
130            content: "This is a test post".to_string(),
131            author: user.clone(),
132        };
133
134        assert_eq!(post.id, "post-1");
135        assert_eq!(post.title, "Test Post");
136        assert_eq!(post.author.name, "Author");
137    }
138
139    #[test]
140    fn test_query_root_creation() {
141        let _query = QueryRoot;
142        // Should create successfully
143    }
144
145    #[test]
146    fn test_graphql_schema_new() {
147        let schema = GraphQLSchema::new();
148        assert!(!schema.schema().sdl().is_empty());
149    }
150
151    #[test]
152    fn test_graphql_schema_default() {
153        let schema = GraphQLSchema::default();
154        assert!(!schema.schema().sdl().is_empty());
155    }
156
157    #[test]
158    fn test_graphql_schema_generate_basic() {
159        let schema = GraphQLSchema::generate_basic_schema();
160        let sdl = schema.schema().sdl();
161        assert!(sdl.contains("Query"));
162    }
163}