1+ /*
2+ * Copyright 2024-2024 the original author or authors.
3+ */
4+
5+ package io .modelcontextprotocol .server ;
6+
7+ import io .modelcontextprotocol .spec .McpSchema ;
8+ import org .junit .jupiter .api .Test ;
9+
10+ import java .util .List ;
11+ import java .util .stream .Collectors ;
12+
13+ import static org .assertj .core .api .Assertions .assertThat ;
14+
15+ /**
16+ * Test to verify the separation of regular resources and resource templates. Regular
17+ * resources (without template parameters) should only appear in resources/list. Template
18+ * resources (containing {}) should only appear in resources/templates/list.
19+ */
20+ public class ResourceTemplateListingTest {
21+
22+ @ Test
23+ void testTemplateResourcesFilteredFromRegularListing () {
24+ // The change we made filters resources containing "{" from the regular listing
25+ // This test verifies that behavior is working correctly
26+
27+ // Given a string with template parameter
28+ String templateUri = "file:///test/{userId}/profile.txt" ;
29+ assertThat (templateUri .contains ("{" )).isTrue ();
30+
31+ // And a regular URI
32+ String regularUri = "file:///test/regular.txt" ;
33+ assertThat (regularUri .contains ("{" )).isFalse ();
34+
35+ // The filter should exclude template URIs
36+ assertThat (!templateUri .contains ("{" )).isFalse ();
37+ assertThat (!regularUri .contains ("{" )).isTrue ();
38+ }
39+
40+ @ Test
41+ void testResourceListingWithMixedResources () {
42+ // Create resource list with both regular and template resources
43+ List <McpSchema .Resource > allResources = List .of (
44+ new McpSchema .Resource ("file:///test/doc1.txt" , "Document 1" , "text/plain" , null , null ),
45+ new McpSchema .Resource ("file:///test/doc2.txt" , "Document 2" , "text/plain" , null , null ),
46+ new McpSchema .Resource ("file:///test/{type}/document.txt" , "Typed Document" , "text/plain" , null , null ),
47+ new McpSchema .Resource ("file:///users/{userId}/files/{fileId}" , "User File" , "text/plain" , null , null ));
48+
49+ // Apply the filter logic from McpAsyncServer line 438
50+ List <McpSchema .Resource > filteredResources = allResources .stream ()
51+ .filter (resource -> !resource .uri ().contains ("{" ))
52+ .collect (Collectors .toList ());
53+
54+ // Verify only regular resources are included
55+ assertThat (filteredResources ).hasSize (2 );
56+ assertThat (filteredResources ).extracting (McpSchema .Resource ::uri )
57+ .containsExactlyInAnyOrder ("file:///test/doc1.txt" , "file:///test/doc2.txt" );
58+ }
59+
60+ @ Test
61+ void testResourceTemplatesListedSeparately () {
62+ // Create mixed resources
63+ List <McpSchema .Resource > resources = List .of (
64+ new McpSchema .Resource ("file:///test/regular.txt" , "Regular Resource" , "text/plain" , null , null ),
65+ new McpSchema .Resource ("file:///test/user/{userId}/profile.txt" , "User Profile" , "text/plain" , null ,
66+ null ));
67+
68+ // Create explicit resource template
69+ McpSchema .ResourceTemplate explicitTemplate = new McpSchema .ResourceTemplate (
70+ "file:///test/document/{docId}/content.txt" , "Document Template" , null , "text/plain" , null );
71+
72+ // Filter regular resources (those without template parameters)
73+ List <McpSchema .Resource > regularResources = resources .stream ()
74+ .filter (resource -> !resource .uri ().contains ("{" ))
75+ .collect (Collectors .toList ());
76+
77+ // Extract template resources (those with template parameters)
78+ List <McpSchema .ResourceTemplate > templateResources = resources .stream ()
79+ .filter (resource -> resource .uri ().contains ("{" ))
80+ .map (resource -> new McpSchema .ResourceTemplate (resource .uri (), resource .name (), resource .description (),
81+ resource .mimeType (), resource .annotations ()))
82+ .collect (Collectors .toList ());
83+
84+ // Verify regular resources list
85+ assertThat (regularResources ).hasSize (1 );
86+ assertThat (regularResources .get (0 ).uri ()).isEqualTo ("file:///test/regular.txt" );
87+
88+ // Verify template resources list includes both extracted and explicit templates
89+ assertThat (templateResources ).hasSize (1 );
90+ assertThat (templateResources .get (0 ).uriTemplate ()).isEqualTo ("file:///test/user/{userId}/profile.txt" );
91+
92+ // In the actual implementation, both would be combined
93+ List <McpSchema .ResourceTemplate > allTemplates = List .of (templateResources .get (0 ), explicitTemplate );
94+ assertThat (allTemplates ).hasSize (2 );
95+ assertThat (allTemplates ).extracting (McpSchema .ResourceTemplate ::uriTemplate )
96+ .containsExactlyInAnyOrder ("file:///test/user/{userId}/profile.txt" ,
97+ "file:///test/document/{docId}/content.txt" );
98+ }
99+
100+ }
0 commit comments