Skip to content

Commit 6184105

Browse files
Return IPopupResult from PopupExtensions.ClosePopupAsync() (#2677)
* Return `IPopupResult` * `dotnet format` * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add `GetMostRecentPopupPage()` * Update XML * Update src/CommunityToolkit.Maui.UnitTests/Extensions/PopupExtensionsTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add Unit Tests * Update XML --------- Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent f143391 commit 6184105

File tree

7 files changed

+289
-114
lines changed

7 files changed

+289
-114
lines changed

src/CommunityToolkit.Maui.UnitTests/Extensions/PopupExtensionsTests.cs

Lines changed: 168 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

12811435
sealed class ViewWithIQueryAttributable : Button, IQueryAttributable

0 commit comments

Comments
 (0)