1+ using System . Diagnostics ;
2+
3+ using BTCPayServer . Plugins . Monero . Services ;
14using BTCPayServer . Rating ;
25using BTCPayServer . Services . Rates ;
6+ using BTCPayServer . Tests ;
37using BTCPayServer . Tests . Mocks ;
48
59using Xunit ;
610using Xunit . Abstractions ;
711
812namespace BTCPayServer . Plugins . IntegrationTests . Monero ;
913
10- public class MoneroPluginIntegrationTest ( ITestOutputHelper helper ) : MoneroAndBitcoinIntegrationTestBase ( helper )
14+ public class MoneroPluginIntegrationTest ( ITestOutputHelper helper ) : MoneroAndBitcoinIntegrationTestBase ( helper ) , IAsyncLifetime
1115{
16+ public Task InitializeAsync ( ) => Task . CompletedTask ;
17+
18+ public async Task DisposeAsync ( )
19+ {
20+ try
21+ {
22+ var removeWalletFromDocker = new ProcessStartInfo
23+ {
24+ FileName = "docker" ,
25+ Arguments = "exec xmr_wallet sh -c \" rm -rf /wallet/*\" " ,
26+ RedirectStandardOutput = true ,
27+ RedirectStandardError = true
28+ } ;
29+
30+ using var process = Process . Start ( removeWalletFromDocker ) ;
31+ if ( process is null )
32+ {
33+ return ;
34+ }
35+
36+ var stdout = await process . StandardOutput . ReadToEndAsync ( ) ;
37+ var stderr = await process . StandardError . ReadToEndAsync ( ) ;
38+
39+ await process . WaitForExitAsync ( ) ;
40+
41+ if ( ! string . IsNullOrWhiteSpace ( stdout ) )
42+ {
43+ Console . WriteLine ( stdout ) ;
44+ }
45+
46+ if ( ! string . IsNullOrWhiteSpace ( stderr ) )
47+ {
48+ Console . WriteLine ( stderr ) ;
49+ }
50+ }
51+ catch ( Exception ex )
52+ {
53+ Console . WriteLine ( $ "Cleanup failed: { ex } ") ;
54+ }
55+ }
56+
1257 [ Fact ]
1358 public async Task EnableMoneroPluginSuccessfully ( )
1459 {
15- await using var s = CreatePlaywrightTester ( ) ;
16- await s . StartAsync ( ) ;
60+ await using var playwrightTester = CreatePlaywrightTester ( ) ;
61+ await playwrightTester . StartAsync ( ) ;
1762
18- if ( s . Server . PayTester . MockRates )
63+ if ( playwrightTester . Server . PayTester . MockRates )
1964 {
20- var rateProviderFactory = s . Server . PayTester . GetService < RateProviderFactory > ( ) ;
65+ var rateProviderFactory = playwrightTester . Server . PayTester . GetService < RateProviderFactory > ( ) ;
2166 rateProviderFactory . Providers . Clear ( ) ;
2267
2368 var coinAverageMock = new MockRateProvider ( ) ;
@@ -33,64 +78,111 @@ public async Task EnableMoneroPluginSuccessfully()
3378 rateProviderFactory . Providers . Add ( "kraken" , kraken ) ;
3479 }
3580
36- await s . RegisterNewUser ( true ) ;
37- await s . CreateNewStore ( preferredExchange : "Kraken" ) ;
38- await s . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
39- await s . Page . Locator ( "input#PrimaryAddress" ) . FillAsync ( "43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L" ) ;
40- await s . Page . Locator ( "input#PrivateViewKey" ) . FillAsync ( "1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e" ) ;
41- await s . Page . Locator ( "input#RestoreHeight" ) . FillAsync ( "0" ) ;
42- await s . Page . Locator ( "input#WalletPassword" ) . FillAsync ( "pass123" ) ;
43- await s . Page . ClickAsync ( "button[name='command'][value='set-wallet-details']" ) ;
44- await s . Page . CheckAsync ( "#Enabled" ) ;
45- await s . Page . SelectOptionAsync ( "#SettlementConfirmationThresholdChoice" , "2" ) ;
46- await s . Page . ClickAsync ( "#SaveButton" ) ;
47- var classList = await s . Page . Locator ( "svg.icon-checkmark" ) . GetAttributeAsync ( "class" ) ;
81+ await playwrightTester . RegisterNewUser ( true ) ;
82+ await playwrightTester . CreateNewStore ( preferredExchange : "Kraken" ) ;
83+ await playwrightTester . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
84+ await playwrightTester . Page . Locator ( "input#PrimaryAddress" )
85+ . FillAsync ( "43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L" ) ;
86+ await playwrightTester . Page . Locator ( "input#PrivateViewKey" )
87+ . FillAsync ( "1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e" ) ;
88+ await playwrightTester . Page . Locator ( "input#RestoreHeight" ) . FillAsync ( "0" ) ;
89+ await playwrightTester . Page . Locator ( "input#WalletPassword" ) . FillAsync ( "pass123" ) ;
90+ await playwrightTester . Page . ClickAsync ( "button[name='command'][value='set-wallet-details']" ) ;
91+ await playwrightTester . Page . CheckAsync ( "#Enabled" ) ;
92+ await playwrightTester . Page . SelectOptionAsync ( "#SettlementConfirmationThresholdChoice" , "2" ) ;
93+ await playwrightTester . Page . ClickAsync ( "#SaveButton" ) ;
94+ var classList = await playwrightTester . Page
95+ . Locator ( "svg.icon-checkmark" )
96+ . GetAttributeAsync ( "class" ) ;
4897 Assert . Contains ( "text-success" , classList ) ;
4998
5099 // Set rate provider
51- await s . Page . Locator ( "#StoreNav -General" ) . ClickAsync ( ) ;
52- await s . Page . Locator ( "#mainNav #StoreNav -Rates" ) . ClickAsync ( ) ;
53- await s . Page . FillAsync ( "#DefaultCurrencyPairs" , "BTC_USD,XMR_USD,XMR_BTC" ) ;
54- await s . Page . SelectOptionAsync ( "#PrimarySource_PreferredExchange" , "kraken" ) ;
55- await s . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
100+ await playwrightTester . Page . Locator ( "#menu-item -General" ) . ClickAsync ( ) ;
101+ await playwrightTester . Page . Locator ( "#menu-item -Rates" ) . ClickAsync ( ) ;
102+ await playwrightTester . Page . FillAsync ( "#DefaultCurrencyPairs" , "BTC_USD,XMR_USD,XMR_BTC" ) ;
103+ await playwrightTester . Page . SelectOptionAsync ( "#PrimarySource_PreferredExchange" , "kraken" ) ;
104+ await playwrightTester . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
56105
57106 // Generate a new invoice
58- await s . Page . Locator ( "a.nav-link[href*='invoices']" ) . ClickAsync ( ) ;
59- await s . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
60- await s . Page . FillAsync ( "#Amount" , "4.20" ) ;
61- await s . Page . FillAsync ( "#BuyerEmail" , "monero@monero.com" ) ;
107+ await playwrightTester . Page . Locator ( "a.nav-link[href*='invoices']" ) . ClickAsync ( ) ;
108+ await playwrightTester . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
109+ await playwrightTester . Page . FillAsync ( "#Amount" , "4.20" ) ;
110+ await playwrightTester . Page . FillAsync ( "#BuyerEmail" , "monero@monero.com" ) ;
62111 await Task . Delay ( TimeSpan . FromSeconds ( 25 ) ) ; // wallet-rpc needs some time to sync. refactor this later
63- await s . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
112+ await playwrightTester . Page . Locator ( "#page-primary" ) . ClickAsync ( ) ;
64113
65114 // View the invoice
66- var href = await s . Page . Locator ( "a[href^='/i/']" ) . GetAttributeAsync ( "href" ) ;
115+ var href = await playwrightTester . Page . Locator ( "a[href^='/i/']" ) . GetAttributeAsync ( "href" ) ;
67116 var invoiceId = href ? . Split ( "/i/" ) . Last ( ) ;
68- await s . Page . Locator ( $ "a[href='/i/{ invoiceId } ']") . ClickAsync ( ) ;
69- await s . Page . ClickAsync ( "#DetailsToggle" ) ;
117+ await playwrightTester . Page . Locator ( $ "a[href='/i/{ invoiceId } ']") . ClickAsync ( ) ;
118+ await playwrightTester . Page . ClickAsync ( "#DetailsToggle" ) ;
70119
71120 // Verify the total fiat amount is $4.20
72- var totalFiat = await s . Page . Locator ( "#PaymentDetails-TotalFiat dd.clipboard-button" ) . InnerTextAsync ( ) ;
121+ var totalFiat = await playwrightTester . Page
122+ . Locator ( "#PaymentDetails-TotalFiat dd.clipboard-button" )
123+ . InnerTextAsync ( ) ;
73124 Assert . Equal ( "$4.20" , totalFiat ) ;
74125
75- await s . Page . GoBackAsync ( ) ;
76- await s . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
126+ await playwrightTester . Page . GoBackAsync ( ) ;
127+ await playwrightTester . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
77128
78129 // Create a new account label
79- await s . Page . FillAsync ( "#NewAccountLabel" , "tst-account" ) ;
80- await s . Page . ClickAsync ( "button[name='command'][value='add-account']" ) ;
130+ await playwrightTester . Page . FillAsync ( "#NewAccountLabel" , "tst-account" ) ;
131+ await playwrightTester . Page . ClickAsync ( "button[name='command'][value='add-account']" ) ;
81132
82133 // Select primary Account Index
83- await s . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
84- await s . Page . SelectOptionAsync ( "#AccountIndex" , "1" ) ;
85- await s . Page . ClickAsync ( "#SaveButton" ) ;
134+ await playwrightTester . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
135+ await playwrightTester . Page . SelectOptionAsync ( "#AccountIndex" , "1" ) ;
136+ await playwrightTester . Page . ClickAsync ( "#SaveButton" ) ;
86137
87138 // Verify selected account index
88- await s . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
89- var selectedValue = await s . Page . Locator ( "#AccountIndex" ) . InputValueAsync ( ) ;
139+ await playwrightTester . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
140+ var selectedValue = await playwrightTester . Page . Locator ( "#AccountIndex" ) . InputValueAsync ( ) ;
90141 Assert . Equal ( "1" , selectedValue ) ;
91142
92143 // Select confirmation time to 0
93- await s . Page . SelectOptionAsync ( "#SettlementConfirmationThresholdChoice" , "3" ) ;
94- await s . Page . ClickAsync ( "#SaveButton" ) ;
144+ await playwrightTester . Page . SelectOptionAsync ( "#SettlementConfirmationThresholdChoice" , "3" ) ;
145+ await playwrightTester . Page . ClickAsync ( "#SaveButton" ) ;
146+
147+ await CleanUp ( playwrightTester ) ;
148+ }
149+
150+ [ Fact ]
151+ public async Task ShouldFailWhenWrongPrimaryAddress ( )
152+ {
153+ await using var playwrightTester = CreatePlaywrightTester ( ) ;
154+ await playwrightTester . StartAsync ( ) ;
155+
156+ await playwrightTester . RegisterNewUser ( true ) ;
157+ await playwrightTester . CreateNewStore ( ) ;
158+ await playwrightTester . Page . Locator ( "a.nav-link[href*='monerolike/XMR']" ) . ClickAsync ( ) ;
159+ await playwrightTester . Page . Locator ( "input#PrimaryAddress" )
160+ . FillAsync ( "wrongprimaryaddressfSF6ZKGFT7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L" ) ;
161+ await playwrightTester . Page . Locator ( "input#PrivateViewKey" )
162+ . FillAsync ( "1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e" ) ;
163+ await playwrightTester . Page . Locator ( "input#RestoreHeight" ) . FillAsync ( "0" ) ;
164+ await playwrightTester . Page . Locator ( "input#WalletPassword" ) . FillAsync ( "pass123" ) ;
165+ await playwrightTester . Page . ClickAsync ( "button[name='command'][value='set-wallet-details']" ) ;
166+ var errorText = await playwrightTester . Page
167+ . Locator ( "div.validation-summary-errors li" )
168+ . InnerTextAsync ( ) ;
169+
170+ Assert . Equal ( "Could not generate view wallet from keys: Failed to parse public address" , errorText ) ;
171+
172+ await CleanUp ( playwrightTester ) ;
173+ }
174+
175+ private static async Task CleanUp ( PlaywrightTester playwrightTester )
176+ {
177+ MoneroRPCProvider moneroRpcProvider = playwrightTester . Server . PayTester . GetService < MoneroRPCProvider > ( ) ;
178+ if ( moneroRpcProvider . IsAvailable ( "XMR" ) )
179+ {
180+ await moneroRpcProvider . CloseWallet ( "XMR" ) ;
181+ await moneroRpcProvider . UpdateSummary ( "XMR" ) ;
182+ }
183+ if ( playwrightTester . Server . PayTester . InContainer )
184+ {
185+ moneroRpcProvider . DeleteWallet ( ) ;
186+ }
95187 }
96188}
0 commit comments