@@ -147,6 +147,7 @@ describe('Suggestions Controller', () => {
147147 'deploySuggestionToEdge' ,
148148 'getByID' ,
149149 'getByStatus' ,
150+ 'getByStatusPaged' ,
150151 'getSuggestionFixes' ,
151152 'patchSuggestion' ,
152153 'patchSuggestionsStatus' ,
@@ -913,6 +914,297 @@ describe('Suggestions Controller', () => {
913914 expect ( error ) . to . have . property ( 'message' , 'Opportunity not found' ) ;
914915 } ) ;
915916
917+ it ( 'gets paged suggestions by status returns bad request if site ID is missing' , async ( ) => {
918+ const response = await suggestionsController . getByStatusPaged ( {
919+ params : {
920+ opportunityId : OPPORTUNITY_ID ,
921+ status : 'NEW' ,
922+ } ,
923+ ...context ,
924+ } ) ;
925+ expect ( response . status ) . to . equal ( 400 ) ;
926+ const error = await response . json ( ) ;
927+ expect ( error ) . to . have . property ( 'message' , 'Site ID required' ) ;
928+ } ) ;
929+
930+ it ( 'gets paged suggestions by status returns bad request if opportunity ID is missing' , async ( ) => {
931+ const response = await suggestionsController . getByStatusPaged ( {
932+ params : {
933+ siteId : SITE_ID ,
934+ status : 'NEW' ,
935+ } ,
936+ ...context ,
937+ } ) ;
938+ expect ( response . status ) . to . equal ( 400 ) ;
939+ const error = await response . json ( ) ;
940+ expect ( error ) . to . have . property ( 'message' , 'Opportunity ID required' ) ;
941+ } ) ;
942+
943+ it ( 'gets paged suggestions by status returns bad request if status is missing' , async ( ) => {
944+ const response = await suggestionsController . getByStatusPaged ( {
945+ params : {
946+ siteId : SITE_ID ,
947+ opportunityId : OPPORTUNITY_ID ,
948+ } ,
949+ ...context ,
950+ } ) ;
951+ expect ( response . status ) . to . equal ( 400 ) ;
952+ const error = await response . json ( ) ;
953+ expect ( error ) . to . have . property ( 'message' , 'Status is required' ) ;
954+ } ) ;
955+
956+ it ( 'gets paged suggestions by status returns bad request if limit is less than 1' , async ( ) => {
957+ const response = await suggestionsController . getByStatusPaged ( {
958+ params : {
959+ siteId : SITE_ID ,
960+ opportunityId : OPPORTUNITY_ID ,
961+ status : 'NEW' ,
962+ limit : - 1 ,
963+ } ,
964+ ...context ,
965+ } ) ;
966+ expect ( response . status ) . to . equal ( 400 ) ;
967+ const error = await response . json ( ) ;
968+ expect ( error ) . to . have . property ( 'message' , 'Page size must be greater than 0' ) ;
969+ } ) ;
970+
971+ it ( 'gets paged suggestions by status returns not found if site does not exist' , async ( ) => {
972+ const response = await suggestionsController . getByStatusPaged ( {
973+ params : {
974+ siteId : SITE_ID_NOT_FOUND ,
975+ opportunityId : OPPORTUNITY_ID ,
976+ status : 'NEW' ,
977+ } ,
978+ ...context ,
979+ } ) ;
980+ expect ( response . status ) . to . equal ( 404 ) ;
981+ const error = await response . json ( ) ;
982+ expect ( error ) . to . have . property ( 'message' , 'Site not found' ) ;
983+ } ) ;
984+
985+ it ( 'gets paged suggestions by status returns forbidden if user does not have access' , async ( ) => {
986+ sandbox . stub ( AccessControlUtil . prototype , 'hasAccess' ) . returns ( false ) ;
987+ const response = await suggestionsController . getByStatusPaged ( {
988+ params : {
989+ siteId : SITE_ID ,
990+ opportunityId : OPPORTUNITY_ID ,
991+ status : 'NEW' ,
992+ } ,
993+ ...context ,
994+ } ) ;
995+ expect ( response . status ) . to . equal ( 403 ) ;
996+ const error = await response . json ( ) ;
997+ expect ( error ) . to . have . property ( 'message' , 'User does not belong to the organization' ) ;
998+ } ) ;
999+
1000+ it ( 'gets paged suggestions by status returns not found if opportunity does not belong to site' , async ( ) => {
1001+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1002+ if ( options ) {
1003+ return Promise . resolve ( {
1004+ data : [ mockSuggestionEntity ( suggs [ 0 ] ) ] ,
1005+ cursor : undefined ,
1006+ } ) ;
1007+ }
1008+ return Promise . resolve ( [ mockSuggestionEntity ( suggs [ 0 ] ) ] ) ;
1009+ } ) ;
1010+ const response = await suggestionsController . getByStatusPaged ( {
1011+ params : {
1012+ siteId : SITE_ID_NOT_ENABLED ,
1013+ opportunityId : OPPORTUNITY_ID ,
1014+ status : 'NEW' ,
1015+ } ,
1016+ ...context ,
1017+ } ) ;
1018+ expect ( response . status ) . to . equal ( 404 ) ;
1019+ const error = await response . json ( ) ;
1020+ expect ( error ) . to . have . property ( 'message' , 'Opportunity not found' ) ;
1021+ } ) ;
1022+
1023+ it ( 'gets paged suggestions by status successfully' , async ( ) => {
1024+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1025+ if ( options ) {
1026+ return Promise . resolve ( {
1027+ data : [ mockSuggestionEntity ( suggs [ 0 ] ) ] ,
1028+ cursor : undefined ,
1029+ } ) ;
1030+ }
1031+ return Promise . resolve ( [ mockSuggestionEntity ( suggs [ 0 ] ) ] ) ;
1032+ } ) ;
1033+ const response = await suggestionsController . getByStatusPaged ( {
1034+ params : {
1035+ siteId : SITE_ID ,
1036+ opportunityId : OPPORTUNITY_ID ,
1037+ status : 'NEW' ,
1038+ } ,
1039+ ...context ,
1040+ } ) ;
1041+ expect ( mockSuggestionDataAccess . Suggestion . allByOpportunityIdAndStatus . calledOnce ) . to . be . true ;
1042+ expect ( response . status ) . to . equal ( 200 ) ;
1043+ const result = await response . json ( ) ;
1044+ expect ( result ) . to . have . property ( 'suggestions' ) ;
1045+ expect ( result . suggestions ) . to . be . an ( 'array' ) . with . lengthOf ( 1 ) ;
1046+ expect ( result ) . to . have . property ( 'pagination' ) ;
1047+ expect ( result . pagination ) . to . deep . equal ( {
1048+ limit : 100 ,
1049+ cursor : null ,
1050+ hasMore : false ,
1051+ } ) ;
1052+ } ) ;
1053+
1054+ it ( 'gets paged suggestions by status with empty results' , async ( ) => {
1055+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1056+ if ( options ) {
1057+ return Promise . resolve ( {
1058+ data : [ ] ,
1059+ cursor : undefined ,
1060+ } ) ;
1061+ }
1062+ return Promise . resolve ( [ ] ) ;
1063+ } ) ;
1064+ const response = await suggestionsController . getByStatusPaged ( {
1065+ params : {
1066+ siteId : SITE_ID ,
1067+ opportunityId : OPPORTUNITY_ID ,
1068+ status : 'NEW' ,
1069+ } ,
1070+ ...context ,
1071+ } ) ;
1072+ expect ( response . status ) . to . equal ( 200 ) ;
1073+ const result = await response . json ( ) ;
1074+ expect ( result . suggestions ) . to . be . an ( 'array' ) . with . lengthOf ( 0 ) ;
1075+ expect ( result . pagination ) . to . deep . equal ( {
1076+ limit : 100 ,
1077+ cursor : null ,
1078+ hasMore : false ,
1079+ } ) ;
1080+ } ) ;
1081+
1082+ it ( 'gets paged suggestions by status successfully when parameters come as strings from URL' , async ( ) => {
1083+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1084+ if ( options ) {
1085+ return Promise . resolve ( {
1086+ data : [ mockSuggestionEntity ( suggs [ 0 ] ) ] ,
1087+ cursor : 'next-cursor-value' ,
1088+ } ) ;
1089+ }
1090+ return Promise . resolve ( [ mockSuggestionEntity ( suggs [ 0 ] ) ] ) ;
1091+ } ) ;
1092+ const response = await suggestionsController . getByStatusPaged ( {
1093+ params : {
1094+ siteId : SITE_ID ,
1095+ opportunityId : OPPORTUNITY_ID ,
1096+ status : 'NEW' ,
1097+ limit : '50' ,
1098+ cursor : 'some-cursor' ,
1099+ } ,
1100+ ...context ,
1101+ } ) ;
1102+ expect ( mockSuggestionDataAccess . Suggestion . allByOpportunityIdAndStatus . calledOnce ) . to . be . true ;
1103+ expect ( response . status ) . to . equal ( 200 ) ;
1104+ const result = await response . json ( ) ;
1105+ expect ( result . suggestions ) . to . be . an ( 'array' ) . with . lengthOf ( 1 ) ;
1106+ expect ( result . pagination ) . to . deep . equal ( {
1107+ limit : 50 ,
1108+ cursor : 'next-cursor-value' ,
1109+ hasMore : true ,
1110+ } ) ;
1111+ } ) ;
1112+
1113+ it ( 'gets paged suggestions by status with cursor parameter calls with correct options' , async ( ) => {
1114+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1115+ if ( options ) {
1116+ return Promise . resolve ( {
1117+ data : [ mockSuggestionEntity ( suggs [ 0 ] ) ] ,
1118+ cursor : 'next-cursor' ,
1119+ } ) ;
1120+ }
1121+ return Promise . resolve ( [ mockSuggestionEntity ( suggs [ 0 ] ) ] ) ;
1122+ } ) ;
1123+
1124+ await suggestionsController . getByStatusPaged ( {
1125+ params : {
1126+ siteId : SITE_ID ,
1127+ opportunityId : OPPORTUNITY_ID ,
1128+ status : 'NEW' ,
1129+ limit : 25 ,
1130+ cursor : 'previous-cursor' ,
1131+ } ,
1132+ ...context ,
1133+ } ) ;
1134+
1135+ expect ( mockSuggestion . allByOpportunityIdAndStatus ) . to . have . been . calledWith (
1136+ OPPORTUNITY_ID ,
1137+ 'NEW' ,
1138+ {
1139+ limit : 25 ,
1140+ cursor : 'previous-cursor' ,
1141+ returnCursor : true ,
1142+ } ,
1143+ ) ;
1144+ } ) ;
1145+
1146+ it ( 'gets paged suggestions by status handles null opportunity correctly' , async ( ) => {
1147+ const mockSuggestionWithNullOpportunity = {
1148+ ...mockSuggestionEntity ( suggs [ 0 ] ) ,
1149+ getOpportunity : sandbox . stub ( ) . returns ( null ) ,
1150+ } ;
1151+
1152+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1153+ if ( options ) {
1154+ return Promise . resolve ( {
1155+ data : [ mockSuggestionWithNullOpportunity ] ,
1156+ cursor : null ,
1157+ } ) ;
1158+ }
1159+ return Promise . resolve ( [ mockSuggestionWithNullOpportunity ] ) ;
1160+ } ) ;
1161+
1162+ const response = await suggestionsController . getByStatusPaged ( {
1163+ params : {
1164+ siteId : SITE_ID ,
1165+ opportunityId : OPPORTUNITY_ID ,
1166+ status : 'NEW' ,
1167+ } ,
1168+ ...context ,
1169+ } ) ;
1170+
1171+ expect ( response . status ) . to . equal ( 404 ) ;
1172+ const error = await response . json ( ) ;
1173+ expect ( error ) . to . have . property ( 'message' , 'Opportunity not found' ) ;
1174+ } ) ;
1175+
1176+ it ( 'gets paged suggestions by status handles opportunity with wrong site ID' , async ( ) => {
1177+ const mockSuggestionWithWrongSite = {
1178+ ...mockSuggestionEntity ( suggs [ 0 ] ) ,
1179+ getOpportunity : sandbox . stub ( ) . returns ( {
1180+ getSiteId : ( ) => SITE_ID_NOT_ENABLED ,
1181+ } ) ,
1182+ } ;
1183+
1184+ mockSuggestion . allByOpportunityIdAndStatus . callsFake ( ( opptyId , status , options ) => {
1185+ if ( options ) {
1186+ return Promise . resolve ( {
1187+ data : [ mockSuggestionWithWrongSite ] ,
1188+ cursor : null ,
1189+ } ) ;
1190+ }
1191+ return Promise . resolve ( [ mockSuggestionWithWrongSite ] ) ;
1192+ } ) ;
1193+
1194+ const response = await suggestionsController . getByStatusPaged ( {
1195+ params : {
1196+ siteId : SITE_ID ,
1197+ opportunityId : OPPORTUNITY_ID ,
1198+ status : 'NEW' ,
1199+ } ,
1200+ ...context ,
1201+ } ) ;
1202+
1203+ expect ( response . status ) . to . equal ( 404 ) ;
1204+ const error = await response . json ( ) ;
1205+ expect ( error ) . to . have . property ( 'message' , 'Opportunity not found' ) ;
1206+ } ) ;
1207+
9161208 it ( 'gets suggestion by ID' , async ( ) => {
9171209 const response = await suggestionsController . getByID ( {
9181210 params : {
0 commit comments