fixture)
+ {
+ _client = fixture.Client;
+ }
+
+ [Fact]
+ public async Task CanGetHomePage()
+ {
+ // Act
+ var response = await _client.GetAsync("/");
+
+ // Assert
+ response.StatusCode.ShouldBe(HttpStatusCode.OK);
+ }
+
+ [Fact]
+ public async Task IncludesFeaturedCampaign_WhenSet()
+ {
+ // Act
+ var response = await _client.GetAsync("/");
+ var content = await response.Content.ReadAsStringAsync();
+
+ // Assert
+ content.ShouldContain(FeaturedCampaignName);
+ }
+
+ [Fact]
+ public async Task IncludesExpectedNumberOfEvents()
+ {
+ // Act
+ var response = await _client.GetAsync("/");
+ var content = await response.Content.ReadAsStringAsync();
+
+ // Assert
+ var newLineFreeContent = Regex.Replace(content, @"\t|\n|\r|\s+", string.Empty);
+ Regex.Matches(newLineFreeContent, "Campaign:").Count.ShouldBe(2);
+ }
+ }
+}
diff --git a/AllReadyApp/AllReady.IntegrationTests/Pages/PrivacyPolicyTests.cs b/AllReadyApp/AllReady.IntegrationTests/Pages/PrivacyPolicyTests.cs
new file mode 100644
index 000000000..28fe1c53d
--- /dev/null
+++ b/AllReadyApp/AllReady.IntegrationTests/Pages/PrivacyPolicyTests.cs
@@ -0,0 +1,28 @@
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Shouldly;
+using Xunit;
+
+namespace AllReady.IntegrationTests.Pages
+{
+ public class PrivacyPolicyTests : IClassFixture>
+ {
+ private readonly HttpClient _client;
+
+ public PrivacyPolicyTests(TestFixture fixture)
+ {
+ _client = fixture.Client;
+ }
+
+ [Fact]
+ public async Task CanGetAboutPage()
+ {
+ // Act
+ var response = await _client.GetAsync("/privacypolicy");
+
+ // Assert
+ response.StatusCode.ShouldBe(HttpStatusCode.OK);
+ }
+ }
+}
diff --git a/AllReadyApp/AllReady.IntegrationTests/TestFixture.cs b/AllReadyApp/AllReady.IntegrationTests/TestFixture.cs
new file mode 100644
index 000000000..c44c70ad5
--- /dev/null
+++ b/AllReadyApp/AllReady.IntegrationTests/TestFixture.cs
@@ -0,0 +1,83 @@
+using System;
+using System.IO;
+using System.Net.Http;
+using System.Reflection;
+using AllReady.Models;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc.ApplicationParts;
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.Mvc.ViewComponents;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace AllReady.IntegrationTests
+{
+ public class TestFixture : IDisposable
+ {
+ private readonly TestServer _server;
+
+ public TestFixture()
+ {
+ var startupAssembly = typeof(TStartup).GetTypeInfo().BaseType.Assembly;
+ var contentRoot = GetProjectPath(startupAssembly);
+
+ var builder = new WebHostBuilder()
+ .UseContentRoot(contentRoot)
+ .ConfigureServices(InitializeServices)
+ .UseEnvironment("Development")
+ .UseStartup(typeof(TStartup));
+
+ _server = new TestServer(builder);
+
+ DbContext = _server.Host.Services.GetService(typeof(AllReadyContext)) as AllReadyContext;
+
+ Client = _server.CreateClient();
+ Client.BaseAddress = new Uri("http://localhost");
+ }
+
+ public HttpClient Client { get; }
+
+ public AllReadyContext DbContext { get; }
+
+ public void Dispose()
+ {
+ Client.Dispose();
+ _server.Dispose();
+ }
+
+ protected virtual void InitializeServices(IServiceCollection services)
+ {
+ var startupAssembly = typeof(TStartup).GetTypeInfo().Assembly;
+ var manager = new ApplicationPartManager();
+ manager.ApplicationParts.Add(new AssemblyPart(startupAssembly));
+ manager.FeatureProviders.Add(new ControllerFeatureProvider());
+ manager.FeatureProviders.Add(new ViewComponentFeatureProvider());
+ services.AddSingleton(manager);
+ }
+
+ // Get the full path to the target project for testing
+ private static string GetProjectPath(Assembly startupAssembly)
+ {
+ var projectName = startupAssembly.GetName().Name;
+ var applicationBasePath = System.AppContext.BaseDirectory;
+ var directoryInfo = new DirectoryInfo(applicationBasePath);
+ do
+ {
+ directoryInfo = directoryInfo.Parent.Parent.Parent.Parent;
+
+ var projectDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, "Web-App"));
+ if (projectDirectoryInfo.Exists)
+ {
+ var projectFileInfo = new FileInfo(Path.Combine(projectDirectoryInfo.FullName, projectName, $"{projectName}.csproj"));
+ if (projectFileInfo.Exists)
+ {
+ return Path.Combine(projectDirectoryInfo.FullName, projectName);
+ }
+ }
+ }
+ while (directoryInfo.Parent != null);
+
+ throw new Exception($"Project root could not be located using the application root {applicationBasePath}.");
+ }
+ }
+}
diff --git a/AllReadyApp/AllReady.IntegrationTests/build/testing.targets b/AllReadyApp/AllReady.IntegrationTests/build/testing.targets
new file mode 100644
index 000000000..3982282d3
--- /dev/null
+++ b/AllReadyApp/AllReady.IntegrationTests/build/testing.targets
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AllReadyApp/AllReadyWebOnly.sln b/AllReadyApp/AllReadyWebOnly.sln
index 11f806661..d005445f1 100644
--- a/AllReadyApp/AllReadyWebOnly.sln
+++ b/AllReadyApp/AllReadyWebOnly.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26730.8
+VisualStudioVersion = 15.0.27130.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{2C1DD2C4-73FF-4D1D-9E88-6B413317FC29}"
EndProject
@@ -32,6 +32,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Builds", "Builds", "{79E5CF
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "AllReady.ScenarioTest", "AllReady.IntegrationTest\AllReady.ScenarioTest.fsproj", "{44055C15-5757-4822-908B-C66B60251C54}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AllReady.IntegrationTests", "AllReady.IntegrationTests\AllReady.IntegrationTests.csproj", "{B45509F1-9C64-4A90-8143-C5D7CDB57904}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{AECA1833-B3D9-4E87-B64C-042FDDBEFF7B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -58,6 +62,10 @@ Global
{44055C15-5757-4822-908B-C66B60251C54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44055C15-5757-4822-908B-C66B60251C54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44055C15-5757-4822-908B-C66B60251C54}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B45509F1-9C64-4A90-8143-C5D7CDB57904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B45509F1-9C64-4A90-8143-C5D7CDB57904}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B45509F1-9C64-4A90-8143-C5D7CDB57904}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B45509F1-9C64-4A90-8143-C5D7CDB57904}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -69,9 +77,8 @@ Global
{BFF4752B-274B-47E5-82FD-9B351792FF2D} = {CB31A2DF-9F47-41D5-AD0F-491C98A8D4CB}
{79E5CFB4-6FF7-4F89-B560-9342FFE91898} = {364DE571-98D2-4F69-8D93-F25F832E7D7A}
{44055C15-5757-4822-908B-C66B60251C54} = {1475C1FD-CE7D-4E6B-83B1-F7F82EA24FF8}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {645EFF42-0422-4249-B544-6038D44E3CDE}
+ {B45509F1-9C64-4A90-8143-C5D7CDB57904} = {1475C1FD-CE7D-4E6B-83B1-F7F82EA24FF8}
+ {AECA1833-B3D9-4E87-B64C-042FDDBEFF7B} = {1475C1FD-CE7D-4E6B-83B1-F7F82EA24FF8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FCAA194F-AD24-45C2-AA51-78C71433DCC0}
diff --git a/AllReadyApp/Web-App/AllReady.UnitTest/Features/Campaigns/FeaturedCampaignQueryHandlerShould.cs b/AllReadyApp/Web-App/AllReady.UnitTest/Features/Campaigns/FeaturedCampaignQueryHandlerShould.cs
index 55b3f5ddc..bd8c2f96a 100644
--- a/AllReadyApp/Web-App/AllReady.UnitTest/Features/Campaigns/FeaturedCampaignQueryHandlerShould.cs
+++ b/AllReadyApp/Web-App/AllReady.UnitTest/Features/Campaigns/FeaturedCampaignQueryHandlerShould.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using AllReady.Features.Campaigns;
using System.Linq;
using System.Threading.Tasks;
@@ -15,7 +15,7 @@ public async Task ReturnASingleCampaignThatIsFeaturedAndHasNotEnded()
// Arrange
var handler = new FeaturedCampaignQueryHandler(Context)
{
- DateTimeOffsetUtcNow = () => new DateTime(2017, 01, 07)
+ DateTimeOffsetUtcNow = () => DateTime.Now
};
// Act
@@ -105,7 +105,7 @@ protected override void LoadTestData()
Featured = true,
ManagingOrganization = org,
Published = true,
- EndDateTime = new DateTime(2012, 1, 1)
+ EndDateTime = DateTime.Now.AddDays(-10)
});
Context.Campaigns.Add(new Campaign
@@ -115,7 +115,7 @@ protected override void LoadTestData()
Featured = true,
ManagingOrganization = org,
Published = true,
- EndDateTime = new DateTime(2018, 1, 1)
+ EndDateTime = DateTime.Now.AddDays(90) // future date
});
Context.Campaigns.Add(new Campaign
@@ -125,7 +125,7 @@ protected override void LoadTestData()
Featured = false,
ManagingOrganization = org,
Published = true,
- EndDateTime = new DateTime(2018, 1, 1)
+ EndDateTime = DateTime.Now.AddDays(90) // future date
});
Context.Campaigns.Add(new Campaign
@@ -135,10 +135,10 @@ protected override void LoadTestData()
Featured = true,
ManagingOrganization = org,
Published = true,
- EndDateTime = new DateTime(2018, 1, 1)
+ EndDateTime = DateTime.Now.AddDays(90) // future date
});
Context.SaveChanges();
}
}
-}
\ No newline at end of file
+}
diff --git a/AllReadyApp/Web-App/AllReady/Startup.cs b/AllReadyApp/Web-App/AllReady/Startup.cs
index c4b8766de..833bc0890 100644
--- a/AllReadyApp/Web-App/AllReady/Startup.cs
+++ b/AllReadyApp/Web-App/AllReady/Startup.cs
@@ -39,7 +39,7 @@ public Startup(IConfiguration configuration)
Configuration = configuration;
Configuration["version"] = new ApplicationEnvironment().ApplicationVersion;
}
-
+
public IConfiguration Configuration { get; }
public IServiceProvider ConfigureServices(IServiceCollection services)
@@ -51,8 +51,7 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
options.AddPolicy("allReady", AllReadyCorsPolicyFactory.BuildAllReadyOpenCorsPolicy());
});
- // Add Entity Framework services to the services container.
- services.AddDbContext(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
+ AddDatabaseServices(services);
Options.LoadConfigurationOptions(services, Configuration);
@@ -77,7 +76,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
if (Configuration["Authentication:Facebook:AppId"] != null)
{
services.AddAuthentication()
- .AddFacebook(options => {
+ .AddFacebook(options =>
+ {
options.AppId = Configuration["authentication:facebook:appid"];
options.AppSecret = Configuration["authentication:facebook:appsecret"];
options.BackchannelHttpHandler = new FacebookBackChannelHandler();
@@ -92,7 +92,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
if (Configuration["Authentication:MicrosoftAccount:ClientId"] != null)
{
services.AddAuthentication()
- .AddMicrosoftAccount(options => {
+ .AddMicrosoftAccount(options =>
+ {
options.ClientId = Configuration["Authentication:MicrosoftAccount:ClientId"];
options.ClientSecret = Configuration["Authentication:MicrosoftAccount:ClientSecret"];
options.Events = new OAuthEvents()
@@ -105,7 +106,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
if (Configuration["Authentication:Twitter:ConsumerKey"] != null)
{
services.AddAuthentication()
- .AddTwitter(options => {
+ .AddTwitter(options =>
+ {
options.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
options.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
options.RetrieveUserDetails = true;
@@ -119,7 +121,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
if (Configuration["Authentication:Google:ClientId"] != null)
{
services.AddAuthentication()
- .AddGoogle(options => {
+ .AddGoogle(options =>
+ {
options.ClientId = Configuration["Authentication:Google:ClientId"];
options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
options.Events = new OAuthEvents()
@@ -167,8 +170,7 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
options.IdleTimeout = TimeSpan.FromMinutes(20);
});
- //Hangfire
- services.AddHangfire(configuration => configuration.UseSqlServerStorage(Configuration["Data:HangfireConnection:ConnectionString"]));
+ AddHangFire(services);
services.AddScoped();
services.AddScoped();
@@ -179,6 +181,26 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
return container.Resolve();
}
+
+ protected virtual void GetDbContext(IServiceCollection services)
+ {
+ // Add Entity Framework services to the services container.
+ services.AddDbContext(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
+ }
+
+
+ protected virtual void AddDatabaseServices(IServiceCollection services)
+ {
+ // Add Entity Framework services to the services container.
+ services.AddDbContext(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
+ }
+
+ protected virtual void AddHangFire(IServiceCollection services)
+ {
+ //Hangfire
+ services.AddHangfire(configuration => configuration.UseSqlServerStorage(Configuration["Data:HangfireConnection:ConnectionString"]));
+ }
+
// Configure is called after ConfigureServices is called.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, AllReadyContext context, SampleDataGenerator sampleData)
{
@@ -224,15 +246,9 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AllReady
context.Database.EnsureDeleted();
}
- //call Migrate here to force the creation of the AllReady database so Hangfire can create its schema under it
- if (purgeRefreshSampleData || !env.IsProduction())
- {
- context.Database.Migrate();
- }
+ MigrateDatabase(purgeRefreshSampleData, env, context);
- ////Hangfire
- app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireDashboardAuthorizationFilter() } });
- app.UseHangfireServer();
+ RegisterHangFire(app);
// Add MVC to the request pipeline.
app.UseMvc(routes =>
@@ -241,16 +257,36 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AllReady
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
+ LoadSeedData(purgeRefreshSampleData, sampleData);
+ }
+
+ protected virtual void RegisterHangFire(IApplicationBuilder app)
+ {
+ app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireDashboardAuthorizationFilter() } });
+ app.UseHangfireServer();
+ }
+
+ protected virtual void LoadSeedData(bool purgeRefreshSampleData, SampleDataGenerator sampleDataGenerator)
+ {
// Add sample data and test admin accounts if specified in Config.Json.
// for production applications, this should either be set to false or deleted.
if (purgeRefreshSampleData || Configuration["SampleData:InsertSampleData"] == "true")
{
- sampleData.InsertTestData();
+ sampleDataGenerator.InsertTestData();
}
if (Configuration["SampleData:InsertTestUsers"] == "true")
{
- sampleData.CreateAdminUser().GetAwaiter().GetResult();
+ sampleDataGenerator.CreateAdminUser().GetAwaiter().GetResult();
+ }
+ }
+
+ protected virtual void MigrateDatabase(bool purgeRefreshSampleData, IHostingEnvironment hostingEnvironment, AllReadyContext context)
+ {
+ //call Migrate here to force the creation of the AllReady database so Hangfire can create its schema under it
+ if (purgeRefreshSampleData || !hostingEnvironment.IsProduction())
+ {
+ context.Database.Migrate();
}
}
}