@@ -36,38 +36,90 @@ public async Task ClosePopup_TokenExpired_ShouldThrowOperationCancelledException
3636 {
3737 // Arrange
3838 var cts = new CancellationTokenSource ( ) ;
39-
39+
4040 // Act
4141 await cts . CancelAsync ( ) ;
42-
42+
4343 // Assert
4444 await Assert . ThrowsAsync < OperationCanceledException > ( ( ) => navigation . ClosePopupAsync ( cts . Token ) ) ;
4545 }
46-
46+
4747 [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
4848 public async Task ClosePopup_NoExistingPopup_ShouldThrowPopupNotFoundException ( )
4949 {
5050 // Arrange
51-
51+
5252 // Act
53-
53+
5454 // Assert
5555 await Assert . ThrowsAsync < PopupNotFoundException > ( ( ) => navigation . ClosePopupAsync ( TestContext . Current . CancellationToken ) ) ;
5656 }
57-
57+
5858 [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
5959 public async Task ClosePopup_PopupBlocked_ShouldThrowPopupBlockedException ( )
6060 {
6161 // Arrange
62-
62+
6363 // Act
6464 navigation . ShowPopup ( new Button ( ) ) ;
6565 await navigation . PushModalAsync ( new ContentPage ( ) ) ;
66-
66+
6767 // Assert
6868 await Assert . ThrowsAsync < PopupBlockedException > ( ( ) => navigation . ClosePopupAsync ( TestContext . Current . CancellationToken ) ) ;
6969 }
7070
71+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
72+ public async Task ClosePopup_NullPage_ShouldThrowArgumentNullException ( )
73+ {
74+ // Arrange
75+
76+ // Act
77+
78+ // Assert
79+ #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
80+ await Assert . ThrowsAsync < ArgumentNullException > ( ( ) => PopupExtensions . ClosePopupAsync ( ( Page ? ) null , TestContext . Current . CancellationToken ) ) ;
81+ #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
82+ }
83+
84+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
85+ public async Task ClosePopup_NullNavigation_ShouldThrowArgumentNullException ( )
86+ {
87+ // Arrange
88+
89+ // Act
90+
91+ // Assert
92+ #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
93+ await Assert . ThrowsAsync < ArgumentNullException > ( ( ) => PopupExtensions . ClosePopupAsync ( ( INavigation ? ) null , TestContext . Current . CancellationToken ) ) ;
94+ #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
95+ }
96+
97+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
98+ public async Task ClosePopupT_NullPage_ShouldThrowArgumentNullException ( )
99+ {
100+ // Arrange
101+
102+ // Act
103+
104+ // Assert
105+ #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
106+ await Assert . ThrowsAsync < ArgumentNullException > ( ( ) => PopupExtensions . ClosePopupAsync ( ( Page ? ) null , 2 , TestContext . Current . CancellationToken ) ) ;
107+ #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
108+ }
109+
110+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
111+ public async Task ClosePopupT_NullNavigation_ShouldThrowArgumentNullException ( )
112+ {
113+ // Arrange
114+
115+ // Act
116+
117+ // Assert
118+ #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
119+ await Assert . ThrowsAsync < ArgumentNullException > ( ( ) => PopupExtensions . ClosePopupAsync ( ( INavigation ? ) null , 2 , TestContext . Current . CancellationToken ) ) ;
120+ #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
121+ }
122+
71123 [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
72124 public async Task ShowPopupAsync_WithPopupType_ShowsPopupAndClosesPopup ( )
73125 {
@@ -80,10 +132,10 @@ public async Task ShowPopupAsync_WithPopupType_ShowsPopupAndClosesPopup()
80132 // Assert
81133 Assert . Single ( navigation . ModalStack ) ;
82134 Assert . IsType < PopupPage > ( navigation . ModalStack [ 0 ] ) ;
83-
135+
84136 // Act
85137 await navigation . ClosePopupAsync ( TestContext . Current . CancellationToken ) ;
86-
138+
87139 // Assert
88140 Assert . Empty ( navigation . ModalStack ) ;
89141 }
@@ -106,10 +158,10 @@ public async Task ShowPopupAsync_Shell_WithPopupType_ShowsPopupAndClosesPopup()
106158 // Assert
107159 Assert . Single ( shellNavigation . ModalStack ) ;
108160 Assert . IsType < PopupPage > ( shellNavigation . ModalStack [ 0 ] ) ;
109-
161+
110162 // Act
111163 await navigation . ClosePopupAsync ( TestContext . Current . CancellationToken ) ;
112-
164+
113165 // Assert
114166 Assert . Empty ( navigation . ModalStack ) ;
115167 }
@@ -127,7 +179,7 @@ public void ShowPopupAsync_WithViewType_ShowsPopup()
127179 Assert . Single ( navigation . ModalStack ) ;
128180 Assert . IsType < PopupPage > ( navigation . ModalStack [ 0 ] ) ;
129181 }
130-
182+
131183 [ Fact ]
132184 public void ShowPopupAsync_WithViewType_SetsCorrectDefaults ( )
133185 {
@@ -138,7 +190,7 @@ public void ShowPopupAsync_WithViewType_SetsCorrectDefaults()
138190
139191 // Act
140192 navigation . ShowPopup ( label ) ;
141-
193+
142194 popupPage = ( PopupPage ) navigation . ModalStack [ 0 ] ;
143195 autogeneratedPopup = ( Popup ) ( ( ( Border ) popupPage . Content . Children [ 0 ] ) . Content ?? throw new InvalidOperationException ( "Border Content cannot be null" ) ) ;
144196
@@ -1276,6 +1328,108 @@ void HandlePopupClosed(object? sender, IPopupResult e)
12761328 popupClosedTCS . SetResult ( e ) ;
12771329 }
12781330 }
1331+
1332+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
1333+ public async Task ClosePopupAsync_ShouldClosePopupUsingNavigationAndReturnResult ( )
1334+ {
1335+ // Arrange
1336+
1337+ if ( Application . Current ? . Windows [ 0 ] . Page is not Page page )
1338+ {
1339+ throw new InvalidOperationException ( "Page cannot be null" ) ;
1340+ }
1341+
1342+ // Act
1343+ page . ShowPopup ( new MockPopup ( ) ) ;
1344+
1345+ // Assert
1346+ Assert . Single ( page . Navigation . ModalStack ) ;
1347+ Assert . IsType < PopupPage > ( page . Navigation . ModalStack [ 0 ] ) ;
1348+
1349+ // Act
1350+ var popupResult = await page . ClosePopupAsync ( TestContext . Current . CancellationToken ) ;
1351+
1352+ // Assert
1353+ Assert . Empty ( page . Navigation . ModalStack ) ;
1354+ Assert . False ( popupResult . WasDismissedByTappingOutsideOfPopup ) ;
1355+ }
1356+
1357+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
1358+ public async Task ClosePopupAsync_ShouldClosePopupUsingPageAndReturnResult ( )
1359+ {
1360+ // Arrange
1361+ if ( Application . Current ? . Windows [ 0 ] . Page is not Page page )
1362+ {
1363+ throw new InvalidOperationException ( "Page cannot be null" ) ;
1364+ }
1365+
1366+ // Act
1367+ page . ShowPopup ( new MockPopup ( ) ) ;
1368+
1369+ // Assert
1370+ Assert . Single ( page . Navigation . ModalStack ) ;
1371+ Assert . IsType < PopupPage > ( page . Navigation . ModalStack [ 0 ] ) ;
1372+
1373+ // Act
1374+ var popupResult = await page . ClosePopupAsync ( page , TestContext . Current . CancellationToken ) ;
1375+
1376+ // Assert
1377+ Assert . Empty ( page . Navigation . ModalStack ) ;
1378+ Assert . False ( popupResult . WasDismissedByTappingOutsideOfPopup ) ;
1379+ }
1380+
1381+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
1382+ public async Task ClosePopupAsyncT_ShouldClosePopupUsingNavigationAndReturnResult ( )
1383+ {
1384+ // Arrange
1385+ const int expectedResult = 2 ;
1386+ if ( Application . Current ? . Windows [ 0 ] . Page is not Page page )
1387+ {
1388+ throw new InvalidOperationException ( "Page cannot be null" ) ;
1389+ }
1390+
1391+ // Act
1392+ page . ShowPopup ( new Popup ( ) ) ;
1393+
1394+ // Assert
1395+ Assert . Single ( page . Navigation . ModalStack ) ;
1396+ Assert . IsType < PopupPage > ( page . Navigation . ModalStack [ 0 ] ) ;
1397+
1398+ // Act
1399+ var popupResult = await page . ClosePopupAsync ( expectedResult , TestContext . Current . CancellationToken ) ;
1400+
1401+ // Assert
1402+ Assert . Empty ( page . Navigation . ModalStack ) ;
1403+ Assert . Equal ( expectedResult , popupResult . Result ) ;
1404+ Assert . False ( popupResult . WasDismissedByTappingOutsideOfPopup ) ;
1405+ }
1406+
1407+ [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
1408+ public async Task ClosePopupAsyncT_ShouldClosePopupUsingPageAndReturnResult ( )
1409+ {
1410+ // Arrange
1411+ const int expectedResult = 2 ;
1412+
1413+ if ( Application . Current ? . Windows [ 0 ] . Page is not Page page )
1414+ {
1415+ throw new InvalidOperationException ( "Page cannot be null" ) ;
1416+ }
1417+
1418+ // Act
1419+ page . ShowPopup ( new MockPopup ( ) ) ;
1420+
1421+ // Assert
1422+ Assert . Single ( page . Navigation . ModalStack ) ;
1423+ Assert . IsType < PopupPage > ( page . Navigation . ModalStack [ 0 ] ) ;
1424+
1425+ // Act
1426+ var popupResult = await page . ClosePopupAsync ( expectedResult , TestContext . Current . CancellationToken ) ;
1427+
1428+ // Assert
1429+ Assert . Empty ( page . Navigation . ModalStack ) ;
1430+ Assert . Equal ( expectedResult , popupResult . Result ) ;
1431+ Assert . False ( popupResult . WasDismissedByTappingOutsideOfPopup ) ;
1432+ }
12791433}
12801434
12811435sealed class ViewWithIQueryAttributable : Button , IQueryAttributable
0 commit comments