@@ -686,7 +686,58 @@ func TestContentArrayToMap(t *testing.T) {
686686 content : []vmcp.Content {
687687 {Type : vmcp .ContentTypeText , Text : "Text" },
688688 {Type : "unknown" , Text : "Should be ignored" },
689- {Type : vmcp .ContentTypeResource , URI : "file://test" },
689+ },
690+ expected : map [string ]any {
691+ "text" : "Text" ,
692+ },
693+ },
694+ {
695+ name : "single text resource content" ,
696+ content : []vmcp.Content {
697+ {Type : vmcp .ContentTypeResource , Text : "SBOM JSON data" , URI : "file://sbom.json" , MimeType : "application/json" },
698+ },
699+ expected : map [string ]any {
700+ "resource" : "SBOM JSON data" ,
701+ },
702+ },
703+ {
704+ name : "single blob resource content uses Data field" ,
705+ content : []vmcp.Content {
706+ {Type : vmcp .ContentTypeResource , Data : "base64blobdata" , URI : "file://binary" , MimeType : "application/octet-stream" },
707+ },
708+ expected : map [string ]any {
709+ "resource" : "base64blobdata" ,
710+ },
711+ },
712+ {
713+ name : "multiple resource contents" ,
714+ content : []vmcp.Content {
715+ {Type : vmcp .ContentTypeResource , Text : "First resource" , URI : "file://a" },
716+ {Type : vmcp .ContentTypeResource , Text : "Second resource" , URI : "file://b" },
717+ {Type : vmcp .ContentTypeResource , Data : "Third blob" , URI : "file://c" },
718+ },
719+ expected : map [string ]any {
720+ "resource" : "First resource" ,
721+ "resource_1" : "Second resource" ,
722+ "resource_2" : "Third blob" ,
723+ },
724+ },
725+ {
726+ name : "mixed text and resource content" ,
727+ content : []vmcp.Content {
728+ {Type : vmcp .ContentTypeText , Text : "summary" },
729+ {Type : vmcp .ContentTypeResource , Text : "SBOM JSON" , URI : "file://sbom.json" },
730+ },
731+ expected : map [string ]any {
732+ "text" : "summary" ,
733+ "resource" : "SBOM JSON" ,
734+ },
735+ },
736+ {
737+ name : "resource link content is still ignored" ,
738+ content : []vmcp.Content {
739+ {Type : vmcp .ContentTypeText , Text : "Text" },
740+ {Type : vmcp .ContentTypeLink , URI : "file://link" , Name : "link" },
690741 },
691742 expected : map [string ]any {
692743 "text" : "Text" ,
@@ -735,6 +786,76 @@ func TestContentArrayToMap(t *testing.T) {
735786 }
736787}
737788
789+ func TestContentArrayToMap_MergeWithStructuredContent (t * testing.T ) {
790+ t .Parallel ()
791+
792+ tests := []struct {
793+ name string
794+ structuredContent map [string ]any
795+ content []vmcp.Content
796+ expected map [string ]any
797+ }{
798+ {
799+ name : "content array keys merged into structuredContent without overwriting" ,
800+ structuredContent : map [string ]any {
801+ "contentType" : "sbom" ,
802+ "format" : "spdx" ,
803+ "size" : float64 (5347 ),
804+ },
805+ content : []vmcp.Content {
806+ {Type : vmcp .ContentTypeText , Text : "summary" },
807+ {Type : vmcp .ContentTypeResource , Text : `{"spdxVersion":"SPDX-2.3"}` , URI : "file://sbom.json" },
808+ },
809+ expected : map [string ]any {
810+ "contentType" : "sbom" ,
811+ "format" : "spdx" ,
812+ "size" : float64 (5347 ),
813+ "text" : "summary" ,
814+ "resource" : `{"spdxVersion":"SPDX-2.3"}` ,
815+ },
816+ },
817+ {
818+ name : "structuredContent keys are not overwritten by content array" ,
819+ structuredContent : map [string ]any {
820+ "text" : "structured text takes priority" ,
821+ },
822+ content : []vmcp.Content {
823+ {Type : vmcp .ContentTypeText , Text : "content array text" },
824+ },
825+ expected : map [string ]any {
826+ "text" : "structured text takes priority" ,
827+ },
828+ },
829+ {
830+ name : "empty content array leaves structuredContent unchanged" ,
831+ structuredContent : map [string ]any {
832+ "key" : "value" ,
833+ },
834+ content : []vmcp.Content {},
835+ expected : map [string ]any {"key" : "value" },
836+ },
837+ }
838+
839+ for _ , tt := range tests {
840+ t .Run (tt .name , func (t * testing.T ) {
841+ t .Parallel ()
842+
843+ // Simulate the merge logic from client.go / mcp_session.go
844+ result := make (map [string ]any , len (tt .structuredContent ))
845+ for k , v := range tt .structuredContent {
846+ result [k ] = v
847+ }
848+ contentMap := conversion .ContentArrayToMap (tt .content )
849+ for k , v := range contentMap {
850+ if _ , exists := result [k ]; ! exists {
851+ result [k ] = v
852+ }
853+ }
854+ assert .Equal (t , tt .expected , result )
855+ })
856+ }
857+ }
858+
738859func TestFromMCPMeta (t * testing.T ) {
739860 t .Parallel ()
740861
0 commit comments