using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using Xunit; using isnd.Entities; using Isn.Abstract; namespace Isn.tests { public sealed class LocalSourceFixture : IDisposable { private readonly HttpListener listener; private readonly Task listenerTask; private readonly string configDirectory; private readonly string originalConfigDirectory; public LocalSourceFixture() { var port = GetFreePort(); var prefix = $"http://127.0.0.1:{port}/"+Constants.APIPrefix; listener = new HttpListener(); listener.Prefixes.Add(prefix); listener.Start(); listenerTask = Task.Run(async () => { while (listener.IsListening) { HttpListenerContext context; try { context = await listener.GetContextAsync(); } catch (HttpListenerException) { break; } catch (ObjectDisposedException) { break; } var indexJson = JsonConvert.SerializeObject(new ApiIndexViewModel(prefix + "index.json") { Version = "3.0.0", Resources = new[] { new Resource(prefix + "put", "PackagePublish/2.0.0") { Comment = "test publish endpoint" } } }); var payload = Encoding.UTF8.GetBytes(indexJson); context.Response.ContentType = "application/json"; context.Response.ContentLength64 = payload.Length; await context.Response.OutputStream.WriteAsync(payload, 0, payload.Length); context.Response.Close(); } }); configDirectory = Path.Combine(Path.GetTempPath(), $"isn-tests-{Guid.NewGuid():N}"); Directory.CreateDirectory(configDirectory); originalConfigDirectory = Environment.GetEnvironmentVariable("ISN_CONFIG_DIR"); Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", configDirectory); SourceUrl = prefix + "index.json"; ConfigureIsnSettings(SourceUrl); Program.LoadConfig(); } public string SourceUrl { get; } public void Dispose() { listener.Close(); if (listenerTask != null) { try { listenerTask.GetAwaiter().GetResult(); } catch (Exception) { } } Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", originalConfigDirectory); if (Directory.Exists(configDirectory)) { Directory.Delete(configDirectory, recursive: true); } } private static int GetFreePort() { var listener = new TcpListener(IPAddress.Loopback, 0); listener.Start(); var port = ((IPEndPoint)listener.LocalEndpoint).Port; listener.Stop(); return port; } private void ConfigureIsnSettings(string sourceUrl) { var configPath = Path.Combine(configDirectory, "config.json"); var settings = new Settings { DataProtectionTitle = "isn", Sources = new Dictionary { [sourceUrl] = new SourceSettings { Alias = "test" } }, DefaultSourceKey = sourceUrl }; File.WriteAllText(configPath, JsonConvert.SerializeObject(settings, Formatting.Indented)); } } public class Tests : IClassFixture { private readonly LocalSourceFixture fixture; public Tests(LocalSourceFixture fixture) { this.fixture = fixture; } [Fact] public void SupportsIsolatedConfigDirectoryOverride() { var tempDir = Path.Combine(Path.GetTempPath(), $"isn-test-{Guid.NewGuid():N}"); Directory.CreateDirectory(tempDir); var originalConfigDir = Environment.GetEnvironmentVariable("ISN_CONFIG_DIR"); var configFile = Path.Combine(tempDir, "config.json"); var expectedSource = "https://example.test/index.json"; var settings = new Settings { DataProtectionTitle = "isn", Sources = new Dictionary { [expectedSource] = new SourceSettings { Alias = "override" } }, DefaultSourceKey = expectedSource }; try { Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", tempDir); File.WriteAllText(configFile, JsonConvert.SerializeObject(settings, Formatting.Indented)); Program.LoadConfig(); Assert.Equal(expectedSource, Program.Settings.DefaultSourceKey); Assert.True(Program.Settings.Sources.ContainsKey(expectedSource)); } finally { Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", originalConfigDir); if (Directory.Exists(tempDir)) { Directory.Delete(tempDir, recursive: true); } } } [Fact] public void HaveADefaultDataProtector() { var pass = "a lame and big pass"; IDataProtector protector = new DefaultDataProtector(); var protectedpass = protector.Protect(pass); var unprotectedpass = protector.UnProtect(protectedpass); Console.WriteLine(protectedpass); Assert.Equal(pass, unprotectedpass); Assert.True(protectedpass != null); Assert.True(protectedpass.Length > 0); } [Fact] public async Task TestHttpClient() { using var client = new HttpClient(); var response = await client.GetAsync(fixture.SourceUrl); var json = await response.Content.ReadAsStringAsync(); var vm = JsonConvert.DeserializeObject(json); Console.WriteLine(JsonConvert.SerializeObject(vm)); Assert.NotNull(vm); Assert.NotNull(vm.Resources); } [Fact] public void TestPush() { Program.LoadConfig(); var report = Program.PushPkg(new[] { Path.Combine(AppContext.BaseDirectory, "dummy.nupkg") }); Assert.NotNull(report); Assert.Single(report); } [Fact] public void GetServerResourcesUsingHttpClientAsyncTest() { var model = SourceHelpers.GetServerResources(fixture.SourceUrl); Console.WriteLine(JsonConvert.SerializeObject(model)); Assert.NotNull(model.Resources); var pub = model.Resources.FirstOrDefault(r => r.Type.StartsWith("PackagePublish/")); Assert.True(pub != null); } } }