@@ -139,3 +139,104 @@ def test_list_resources(self, temp_file: Path):
139139 resources = manager .list_resources ()
140140 assert len (resources ) == 2
141141 assert resources == [resource1 , resource2 ]
142+
143+ @pytest .mark .anyio
144+ async def test_context_injection_in_template (self ):
145+ """Test that context is injected when getting a resource from a template."""
146+ from mcp .server .fastmcp import Context , FastMCP
147+
148+ manager = ResourceManager ()
149+
150+ def resource_with_context (name : str , ctx : Context ) -> str :
151+ assert isinstance (ctx , Context )
152+ return f"Hello, { name } !"
153+
154+ template = ResourceTemplate .from_function (
155+ fn = resource_with_context ,
156+ uri_template = "greet://{name}" ,
157+ name = "greeter" ,
158+ )
159+ manager ._templates [template .uri_template ] = template
160+
161+ mcp = FastMCP ()
162+ ctx = mcp .get_context ()
163+
164+ resource = await manager .get_resource (AnyUrl ("greet://world" ), context = ctx )
165+ assert isinstance (resource , FunctionResource )
166+ content = await resource .read ()
167+ assert content == "Hello, world!"
168+
169+ @pytest .mark .anyio
170+ async def test_context_injection_in_async_template (self ):
171+ """Test that context is properly injected in async template functions."""
172+ from mcp .server .fastmcp import Context , FastMCP
173+
174+ manager = ResourceManager ()
175+
176+ async def async_resource (name : str , ctx : Context ) -> str :
177+ assert isinstance (ctx , Context )
178+ return f"Async Hello, { name } !"
179+
180+ template = ResourceTemplate .from_function (
181+ fn = async_resource ,
182+ uri_template = "async-greet://{name}" ,
183+ name = "async-greeter" ,
184+ )
185+ manager ._templates [template .uri_template ] = template
186+
187+ mcp = FastMCP ()
188+ ctx = mcp .get_context ()
189+
190+ resource = await manager .get_resource (
191+ AnyUrl ("async-greet://world" ), context = ctx
192+ )
193+ assert isinstance (resource , FunctionResource )
194+ content = await resource .read ()
195+ assert content == "Async Hello, world!"
196+
197+ @pytest .mark .anyio
198+ async def test_optional_context_in_template (self ):
199+ """Test that context is optional when getting a resource from a template."""
200+ from mcp .server .fastmcp import Context
201+
202+ manager = ResourceManager ()
203+
204+ def resource_with_optional_context (
205+ name : str , ctx : Context | None = None
206+ ) -> str :
207+ return f"Hello, { name } !"
208+
209+ template = ResourceTemplate .from_function (
210+ fn = resource_with_optional_context ,
211+ uri_template = "greet://{name}" ,
212+ name = "greeter" ,
213+ )
214+ manager ._templates [template .uri_template ] = template
215+
216+ resource = await manager .get_resource (AnyUrl ("greet://world" ))
217+ assert isinstance (resource , FunctionResource )
218+ content = await resource .read ()
219+ assert content == "Hello, world!"
220+
221+ @pytest .mark .anyio
222+ async def test_context_error_handling_in_template (self ):
223+ """Test error handling when context injection fails in a template."""
224+ from mcp .server .fastmcp import Context , FastMCP
225+
226+ manager = ResourceManager ()
227+
228+ def failing_resource (name : str , ctx : Context ) -> str :
229+ raise ValueError ("Test error" )
230+
231+ template = ResourceTemplate .from_function (
232+ fn = failing_resource ,
233+ uri_template = "greet://{name}" ,
234+ name = "greeter" ,
235+ )
236+ manager ._templates [template .uri_template ] = template
237+
238+ mcp = FastMCP ()
239+ ctx = mcp .get_context ()
240+
241+ with pytest .raises (ValueError , match = "Error creating resource from template" ):
242+ await manager .get_resource (AnyUrl ("greet://world" ), context = ctx )
0 commit comments