1
1
using System . ComponentModel ;
2
2
using CommunityToolkit . Maui . Core ;
3
3
using CommunityToolkit . Maui . UnitTests . Mocks ;
4
+ using CommunityToolkit . Maui . UnitTests . Views ;
4
5
using CommunityToolkit . Maui . Views ;
6
+ using FluentAssertions ;
5
7
using Xunit ;
6
8
7
9
namespace CommunityToolkit . Maui . UnitTests ;
@@ -10,12 +12,9 @@ public class PopupServiceTests : BaseHandlerTest
10
12
{
11
13
public PopupServiceTests ( )
12
14
{
13
- var page = new ContentPage ( ) ;
14
-
15
- static PopupServiceTests ( )
16
- {
15
+ var page = new MockPage ( new MockPageViewModel ( ) ) ;
17
16
var serviceCollection = new ServiceCollection ( ) ;
18
- PopupService . AddTransientPopup < MockPopup , MockPageViewModel > ( serviceCollection ) ;
17
+ PopupService . AddPopup < MockPopup , MockPageViewModel > ( serviceCollection , ServiceLifetime . Transient ) ;
19
18
CreateViewHandler < MockPageHandler > ( page ) ;
20
19
21
20
Assert . NotNull ( Application . Current ) ;
@@ -29,7 +28,7 @@ public async Task ShowPopupAsyncWithNullOnPresentingShouldThrowArgumentNullExcep
29
28
30
29
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
31
30
await Assert . ThrowsAsync < ArgumentNullException > ( ( ) =>
32
- popupService . ShowPopupAsync < INotifyPropertyChanged > ( onPresenting : null , token : CancellationToken . None ) ) ;
31
+ popupService . ShowPopupAsync < INotifyPropertyChanged > ( new PopupOptions ( ) , CancellationToken . None ) ) ;
33
32
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
34
33
}
35
34
@@ -43,7 +42,7 @@ public async Task ShowPopupAsync_CancellationTokenExpired()
43
42
// Ensure CancellationToken has expired
44
43
await Task . Delay ( 100 , CancellationToken . None ) ;
45
44
46
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( token : cts . Token ) ) ;
45
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , cts . Token ) ) ;
47
46
}
48
47
49
48
[ Fact ( Timeout = ( int ) TestDuration . Short ) ]
@@ -56,19 +55,7 @@ public async Task ShowPopupAsync_CancellationTokenCanceled()
56
55
// Ensure CancellationToken has expired
57
56
await cts . CancelAsync ( ) ;
58
57
59
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( token : cts . Token ) ) ;
60
- }
61
-
62
- [ Fact ( Timeout = ( int ) TestDuration . Short ) ]
63
- public async Task ShowPopupAsyncShouldThrowInvalidOperationExceptionWhenNoViewModelIsRegistered ( )
64
- {
65
- var popupInstance = new MockMismatchedPopup ( ) ;
66
- var popupViewModel = new MockPageViewModel ( ) ;
67
-
68
- SetupTest ( popupInstance , ( ) => popupViewModel , out var popupService ) ;
69
-
70
- await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( token : CancellationToken . None ) ) ;
71
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( cts . Token ) ) ;
58
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , cts . Token ) ) ;
72
59
}
73
60
74
61
[ Fact ( Timeout = ( int ) TestDuration . Medium ) ]
@@ -78,7 +65,7 @@ public async Task ShowPopupAsyncShouldValidateProperBindingContext()
78
65
var popupInstance = ServiceProvider . GetRequiredService < MockSelfClosingPopup > ( ) ;
79
66
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
80
67
81
- await popupService . ShowPopupAsync < MockPageViewModel > ( token : CancellationToken . None ) ;
68
+ await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , CancellationToken . None ) ;
82
69
83
70
Assert . Same ( popupInstance . BindingContext , popupViewModel ) ;
84
71
}
@@ -99,7 +86,7 @@ public async Task ShowPopupAsyncWithOnPresenting_CancellationTokenExpired()
99
86
// Ensure CancellationToken has expired
100
87
await Task . Delay ( 100 , CancellationToken . None ) ;
101
88
102
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( viewModel => viewModel . HasLoaded = true , token : cts . Token ) ) ;
89
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
103
90
}
104
91
105
92
[ Fact ( Timeout = ( int ) TestDuration . Short ) ]
@@ -112,7 +99,7 @@ public async Task ShowPopupAsyncWithOnPresenting_CancellationTokenCanceled()
112
99
// Ensure CancellationToken has expired
113
100
await cts . CancelAsync ( ) ;
114
101
115
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( viewModel => viewModel . HasLoaded = true , token : cts . Token ) ) ;
102
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
116
103
}
117
104
118
105
[ Fact ( Timeout = ( int ) TestDuration . Medium ) ]
@@ -121,7 +108,7 @@ public async Task ShowPopupAsyncWithOnPresentingShouldBeInvoked()
121
108
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
122
109
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
123
110
124
- await popupService . ShowPopupAsync < MockPageViewModel > ( onPresenting : viewModel => viewModel . HasLoaded = true , token : CancellationToken . None ) ;
111
+ await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , CancellationToken . None ) ;
125
112
126
113
Assert . True ( popupViewModel . HasLoaded ) ;
127
114
}
@@ -132,51 +119,24 @@ public async Task ShowPopupAsyncShouldReturnResultOnceClosed()
132
119
var mockPopup = ServiceProvider . GetRequiredService < MockSelfClosingPopup > ( ) ;
133
120
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
134
121
135
- var result = await popupService . ShowPopupAsync < MockPageViewModel > ( token : CancellationToken . None ) ;
122
+ var result = await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , CancellationToken . None ) ;
136
123
137
- Assert . Same ( expectedResult , result ) ;
138
124
Assert . Same ( mockPopup . Result , result ) ;
139
125
}
140
126
141
- [ Fact ]
142
- public void ShowPopupWithNullOnPresentingShouldThrowArgumentNullException ( )
143
- {
144
- var popupService = new PopupService ( ServiceProvider , new MockDispatcherProvider ( ) ) ;
145
-
146
- #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
147
- Assert . Throws < ArgumentNullException > ( ( ) => popupService . ShowPopup < INotifyPropertyChanged > ( onPresenting : null ) ) ;
148
- #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
149
- }
150
-
151
- [ Fact ]
152
- public void ShowPopupShouldThrowInvalidOperationExceptionWhenNoViewModelIsRegistered ( )
153
- {
154
- var popupInstance = new MockMismatchedPopup ( ) ;
155
- var popupViewModel = new MockPageViewModel ( ) ;
156
-
157
- SetupTest ( popupInstance , ( ) => popupViewModel , out var popupService ) ;
158
-
159
- Assert . Throws < InvalidOperationException > ( ( ) => popupService . ShowPopup < MockPageViewModel > ( ) ) ;
160
- }
161
-
162
127
[ Fact ]
163
128
public void ShowPopupWithOnPresentingShouldBeInvoked ( )
164
129
{
165
130
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
166
131
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
167
132
168
- popupService . ShowPopup < MockPageViewModel > ( onPresenting : viewModel => viewModel . HasLoaded = true ) ;
133
+ popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , CancellationToken . None ) ;
169
134
170
135
Assert . True ( popupViewModel . HasLoaded ) ;
171
136
}
172
-
173
- sealed class UnregisteredViewModel : INotifyPropertyChanged
174
- {
175
- public event PropertyChangedEventHandler ? PropertyChanged;
176
- }
177
137
}
178
138
179
- sealed class MockSelfClosingPopup : ContentView
139
+ sealed class MockSelfClosingPopup : Popup
180
140
{
181
141
public MockSelfClosingPopup ( MockPageViewModel viewModel , object ? result = null )
182
142
{
@@ -185,13 +145,4 @@ public MockSelfClosingPopup(MockPageViewModel viewModel, object? result = null)
185
145
}
186
146
187
147
public new object ? Result { get ; }
188
-
189
- internal override async void OnOpened ( )
190
- {
191
- base . OnOpened ( ) ;
192
-
193
- await Task . Delay ( TimeSpan . FromMilliseconds ( 500 ) ) ;
194
-
195
- Close ( Result ) ;
196
- }
197
148
}
0 commit comments