@@ -586,6 +586,103 @@ func TestGetMCPServerTool_PassesToolNameFilter(t *testing.T) {
586586 assert .Equal (t , "list_problems" , * toolRepo .capturedListOptions .ToolName )
587587}
588588
589+ // --- Pagination default tests ---
590+
591+ func TestListMCPServers_EmptyOrderByUsesDefault (t * testing.T ) {
592+ // When OrderBy and SortOrder are not specified (empty strings from the API layer),
593+ // the pagination must still apply default ordering ("id" / "ASC") so that
594+ // cursor-based pagination works correctly on subsequent pages.
595+ repo := & mockMCPServerRepo {listResult : emptyList ()}
596+ cat := newTestCatalog (repo , nil )
597+
598+ _ , err := cat .ListMCPServers (context .Background (), ListMCPServersParams {
599+ FilterQuery : "license='Apache 2.0'" ,
600+ PageSize : 10 ,
601+ // OrderBy and SortOrder are zero values (empty strings)
602+ })
603+ require .NoError (t , err )
604+
605+ pagination := repo .capturedOptions .Pagination
606+ // The pagination must resolve to the defaults ("id" / "ASC").
607+ // Either OrderBy is nil (so GetOrderBy falls through to DefaultOrderBy),
608+ // or it is set to the explicit default value — but it must NOT be a
609+ // pointer to an empty string, which would skip the ORDER BY clause.
610+ orderBy := pagination .GetOrderBy ()
611+ sortOrder := pagination .GetSortOrder ()
612+ assert .Equal (t , "id" , orderBy , "expected default orderBy 'id' when param is empty" )
613+ assert .Equal (t , "ASC" , sortOrder , "expected default sortOrder 'ASC' when param is empty" )
614+ }
615+
616+ func TestListMCPServers_EmptyOrderByPaginationNotNilEmptyString (t * testing.T ) {
617+ // Regression: when OrderBy/SortOrder are empty, they must NOT be set as
618+ // pointers to empty strings. The downstream paginator skips ORDER BY when
619+ // both are empty, but still applies the cursor WHERE clause, causing
620+ // non-deterministic results and empty second pages.
621+ repo := & mockMCPServerRepo {listResult : emptyList ()}
622+ cat := newTestCatalog (repo , nil )
623+
624+ _ , err := cat .ListMCPServers (context .Background (), ListMCPServersParams {
625+ FilterQuery : "license='Apache 2.0'" ,
626+ PageSize : 1 ,
627+ // OrderBy and SortOrder deliberately left as zero values
628+ })
629+ require .NoError (t , err )
630+
631+ pagination := repo .capturedOptions .Pagination
632+
633+ // If OrderBy is non-nil, it must not point to an empty string.
634+ if pagination .OrderBy != nil {
635+ assert .NotEmpty (t , * pagination .OrderBy , "OrderBy must not be a pointer to an empty string" )
636+ }
637+ // If SortOrder is non-nil, it must not point to an empty string.
638+ if pagination .SortOrder != nil {
639+ assert .NotEmpty (t , * pagination .SortOrder , "SortOrder must not be a pointer to an empty string" )
640+ }
641+ }
642+
643+ func TestListMCPServers_ExplicitOrderByIsPreserved (t * testing.T ) {
644+ // When OrderBy/SortOrder are explicitly provided, they should be passed through.
645+ repo := & mockMCPServerRepo {listResult : emptyList ()}
646+ cat := newTestCatalog (repo , nil )
647+
648+ _ , err := cat .ListMCPServers (context .Background (), ListMCPServersParams {
649+ FilterQuery : "license='Apache 2.0'" ,
650+ PageSize : 10 ,
651+ OrderBy : "CREATE_TIME" ,
652+ SortOrder : "DESC" ,
653+ })
654+ require .NoError (t , err )
655+
656+ pagination := repo .capturedOptions .Pagination
657+ assert .Equal (t , "CREATE_TIME" , pagination .GetOrderBy ())
658+ assert .Equal (t , "DESC" , pagination .GetSortOrder ())
659+ }
660+
661+ func TestListMCPServerTools_EmptyOrderByUsesDefault (t * testing.T ) {
662+ // Same bug applies to ListMCPServerTools — empty OrderBy/SortOrder must
663+ // resolve to defaults for correct cursor-based pagination.
664+ serverEntity := & models.MCPServerImpl {
665+ ID : serverID (1 ),
666+ Attributes : & models.MCPServerAttributes {Name : serverName ("test-server" )},
667+ }
668+ repo := & mockMCPServerRepo {getResult : serverEntity }
669+ toolRepo := & mockMCPServerToolRepo {listResult : toolList ()}
670+ cat := newTestCatalogWithToolRepo (repo , toolRepo , nil )
671+
672+ _ , err := cat .ListMCPServerTools (context .Background (), "1" , ListMCPServerToolsParams {
673+ PageSize : 10 ,
674+ // OrderBy and SortOrder are zero values (empty strings)
675+ })
676+ require .NoError (t , err )
677+
678+ require .NotNil (t , toolRepo .capturedListOptions )
679+ pagination := toolRepo .capturedListOptions .Pagination
680+ orderBy := pagination .GetOrderBy ()
681+ sortOrder := pagination .GetSortOrder ()
682+ assert .Equal (t , "id" , orderBy , "expected default orderBy 'id' when param is empty" )
683+ assert .Equal (t , "ASC" , sortOrder , "expected default sortOrder 'ASC' when param is empty" )
684+ }
685+
589686func TestGetMCPServer_IncludeToolsUsesAccurateCount (t * testing.T ) {
590687 serverEntity := & models.MCPServerImpl {
591688 ID : serverID (1 ),
0 commit comments