Skip to content

Commit 38f62bc

Browse files
committed
Custom integration test for issue #30
1 parent 26974d6 commit 38f62bc

2 files changed

Lines changed: 132 additions & 23 deletions

File tree

test/FubarDev.FtpServer.Tests/FtpServerFixture.cs

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@
1313
namespace FubarDev.FtpServer.Tests
1414
{
1515
/// <summary>
16-
/// Fixture that initializes an FTP server
16+
/// Fixture that initializes an FTP server.
1717
/// </summary>
1818
public class FtpServerFixture : IAsyncLifetime
1919
{
20-
private readonly IServiceProvider _serviceProvider;
20+
private ServiceProvider? _serviceProvider;
2121
private IFtpServer? _server;
2222

2323
/// <summary>
24-
/// Initializes a new instance of the <see cref="FtpServerFixture"/> class.
24+
/// Gets the FTP server.
2525
/// </summary>
26-
public FtpServerFixture()
26+
public IFtpServer Server => _server ?? throw new InvalidOperationException();
27+
28+
/// <inheritdoc />
29+
public Task InitializeAsync()
2730
{
2831
var services = new ServiceCollection()
2932
.AddLogging(
@@ -36,33 +39,50 @@ public FtpServerFixture()
3639
lb.AddFilter("FubarDev.FtpServer", LogLevel.Trace);
3740
})
3841
.AddFtpServer(
39-
opt => opt.EnableAnonymousAuthentication()
40-
.UseSingleRoot()
41-
.UseInMemoryFileSystem())
42-
.Configure<FtpServerOptions>(opt =>
43-
{
44-
// IPv4 localhost
45-
opt.ServerAddress = "127.0.0.1";
46-
47-
// Dynamic port
48-
opt.Port = 0;
49-
});
42+
opt => Configure(opt));
43+
services = Configure(services);
5044
_serviceProvider = services.BuildServiceProvider(true);
45+
_server = _serviceProvider.GetRequiredService<IFtpServer>();
46+
return _server.StartAsync(default);
5147
}
5248

53-
public IFtpServer Server => _server ?? throw new InvalidOperationException();
54-
5549
/// <inheritdoc />
56-
public Task InitializeAsync()
50+
public async Task DisposeAsync()
5751
{
58-
_server = _serviceProvider.GetRequiredService<IFtpServer>();
59-
return _server.StartAsync(default);
52+
await Server.StopAsync(default).ConfigureAwait(false);
53+
_serviceProvider?.Dispose();
6054
}
6155

62-
/// <inheritdoc />
63-
public Task DisposeAsync()
56+
/// <summary>
57+
/// Basic FTP server configuration for the basic configuration through <see cref="Configure(IFtpServerBuilder)"/>.
58+
/// </summary>
59+
/// <param name="services">The service collection.</param>
60+
/// <returns>The modified service collection.</returns>
61+
protected virtual IServiceCollection Configure(IServiceCollection services)
62+
{
63+
return services
64+
.Configure<FtpServerOptions>(
65+
opt =>
66+
{
67+
// IPv4 localhost
68+
opt.ServerAddress = "127.0.0.1";
69+
70+
// Dynamic port
71+
opt.Port = 0;
72+
});
73+
}
74+
75+
/// <summary>
76+
/// Basic configuration using the FTP server builder.
77+
/// </summary>
78+
/// <param name="builder">The FTP server builder used for the configuration.</param>
79+
/// <returns>The modified FTP server builder.</returns>
80+
protected virtual IFtpServerBuilder Configure(IFtpServerBuilder builder)
6481
{
65-
return Server.StopAsync(default);
82+
return builder
83+
.EnableAnonymousAuthentication()
84+
.UseSingleRoot()
85+
.UseInMemoryFileSystem();
6686
}
6787
}
6888
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// <copyright file="Issue30CustomFtpUser.cs" company="Fubar Development Junker">
2+
// Copyright (c) Fubar Development Junker. All rights reserved.
3+
// </copyright>
4+
5+
using System.Security.Claims;
6+
using System.Threading.Tasks;
7+
8+
using FluentFTP;
9+
10+
using FubarDev.FtpServer.AccountManagement;
11+
12+
using Microsoft.Extensions.DependencyInjection;
13+
14+
using Xunit;
15+
16+
namespace FubarDev.FtpServer.Tests.Issues
17+
{
18+
public class Issue30CustomFtpUser : IClassFixture<Issue30CustomFtpUser.Issue30FtpServerFixture>
19+
{
20+
private readonly IFtpServer _server;
21+
22+
public Issue30CustomFtpUser(Issue30FtpServerFixture ftpServerFixture)
23+
{
24+
_server = ftpServerFixture.Server;
25+
}
26+
27+
[Fact]
28+
public async Task LoginSucceedsWithTester()
29+
{
30+
using var client = new FtpClient("127.0.0.1", _server.Port, "tester", "test");
31+
await client.ConnectAsync();
32+
}
33+
34+
[Fact]
35+
public async Task LoginFailsWithWrongUserName()
36+
{
37+
using var client = new FtpClient("127.0.0.1", _server.Port, "testerX", "test");
38+
await Assert.ThrowsAsync<FtpAuthenticationException>(() => client.ConnectAsync())
39+
.ConfigureAwait(false);
40+
}
41+
42+
[Fact]
43+
public async Task LoginFailsWithWrongPassword()
44+
{
45+
using var client = new FtpClient("127.0.0.1", _server.Port, "tester", "testX");
46+
await Assert.ThrowsAsync<FtpAuthenticationException>(() => client.ConnectAsync())
47+
.ConfigureAwait(false);
48+
}
49+
50+
/// <summary>
51+
/// Custom configuration of the FTP server.
52+
/// </summary>
53+
public class Issue30FtpServerFixture : FtpServerFixture
54+
{
55+
/// <inheritdoc />
56+
protected override IFtpServerBuilder Configure(IFtpServerBuilder builder)
57+
{
58+
return builder
59+
.UseSingleRoot()
60+
.UseInMemoryFileSystem();
61+
}
62+
63+
/// <inheritdoc />
64+
protected override IServiceCollection Configure(IServiceCollection services)
65+
{
66+
return base.Configure(services)
67+
.AddSingleton<IMembershipProvider, CustomMembershipProvider>();
68+
}
69+
}
70+
71+
private class CustomMembershipProvider : IMembershipProvider
72+
{
73+
/// <inheritdoc />
74+
public Task<MemberValidationResult> ValidateUserAsync(string username, string password)
75+
{
76+
if (username == "tester" && password == "test")
77+
{
78+
var identity = new ClaimsIdentity();
79+
return Task.FromResult(
80+
new MemberValidationResult(
81+
MemberValidationStatus.AuthenticatedUser,
82+
new ClaimsPrincipal(identity)));
83+
}
84+
85+
return Task.FromResult(new MemberValidationResult(MemberValidationStatus.InvalidLogin));
86+
}
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)