added signalR to Integration Test

pull/4/head
kayone 11 years ago
parent 47af488e4b
commit 5ab873150e

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nancy; using Nancy;
namespace NzbDrone.Api.Extensions namespace NzbDrone.Api.Extensions

@ -1,15 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Api.Mapping; using NzbDrone.Api.Mapping;
using NzbDrone.Api.Validation; using NzbDrone.Api.Validation;
namespace NzbDrone.Api.RootFolders namespace NzbDrone.Api.RootFolders
{ {
public class RootFolderModule : NzbDroneRestModule<RootFolderResource> public class RootFolderModule : NzbDroneRestModuleWithSignalR<RootFolderResource, RootFolder>
{ {
private readonly IRootFolderService _rootFolderService; private readonly IRootFolderService _rootFolderService;
public RootFolderModule(IRootFolderService rootFolderService) public RootFolderModule(IRootFolderService rootFolderService, ICommandExecutor commandExecutor)
: base(commandExecutor)
{ {
_rootFolderService = rootFolderService; _rootFolderService = rootFolderService;
@ -18,7 +20,7 @@ namespace NzbDrone.Api.RootFolders
CreateResource = CreateRootFolder; CreateResource = CreateRootFolder;
DeleteResource = DeleteFolder; DeleteResource = DeleteFolder;
SharedValidator.RuleFor(c=>c.Path).IsValidPath(); SharedValidator.RuleFor(c => c.Path).IsValidPath();
} }
private RootFolderResource GetRootFolder(int id) private RootFolderResource GetRootFolder(int id)

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
[Test] [Test]
public void should_return_one_drive_when_only_one_root_dir_exists() public void should_return_one_drive_when_only_one_root_dir_exists()
{ {
Mocker.GetMock<IBasicRepository<RootFolder>>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } }); .Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });
@ -41,7 +41,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
[Test] [Test]
public void should_return_one_drive_when_two_rootDirs_on_the_same_drive_exist() public void should_return_one_drive_when_two_rootDirs_on_the_same_drive_exist()
{ {
Mocker.GetMock<IBasicRepository<RootFolder>>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" }, .Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
new RootFolder { Id = 2, Path = @"C:\Test\TV2" }}); new RootFolder { Id = 2, Path = @"C:\Test\TV2" }});
@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
[Test] [Test]
public void should_return_two_drives_when_two_rootDirs_on_the_different_drive_exist() public void should_return_two_drives_when_two_rootDirs_on_the_different_drive_exist()
{ {
Mocker.GetMock<IBasicRepository<RootFolder>>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" }, .Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" },
new RootFolder { Id = 2, Path = @"D:\Test\TV" }}); new RootFolder { Id = 2, Path = @"D:\Test\TV" }});
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
[Test] [Test]
public void should_skip_rootDir_if_not_found_on_disk() public void should_skip_rootDir_if_not_found_on_disk()
{ {
Mocker.GetMock<IBasicRepository<RootFolder>>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } }); .Returns(new List<RootFolder> { new RootFolder { Id = 1, Path = @"C:\Test\TV" } });

@ -1,13 +1,10 @@
 using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -25,7 +22,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Setup(m => m.FolderExists(It.IsAny<string>())) .Setup(m => m.FolderExists(It.IsAny<string>()))
.Returns(true); .Returns(true);
Mocker.GetMock<IBasicRepository<RootFolder>>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder>()); .Returns(new List<RootFolder>());
} }
@ -45,7 +42,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
Subject.Add(root); Subject.Add(root);
Mocker.GetMock<IBasicRepository<RootFolder>>().Verify(c => c.Insert(root), Times.Once()); Mocker.GetMock<IRootFolderRepository>().Verify(c => c.Insert(root), Times.Once());
} }
[Test] [Test]
@ -60,7 +57,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
public void should_be_able_to_remove_root_dir() public void should_be_able_to_remove_root_dir()
{ {
Subject.Remove(1); Subject.Remove(1);
Mocker.GetMock<IBasicRepository<RootFolder>>().Verify(c => c.Delete(1), Times.Once()); Mocker.GetMock<IRootFolderRepository>().Verify(c => c.Delete(1), Times.Once());
} }
[Test] [Test]
@ -68,7 +65,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
{ {
WithNoneExistingFolder(); WithNoneExistingFolder();
Mocker.GetMock<IBasicRepository<RootFolder>>().Setup(c => c.All()).Returns(new List<RootFolder>()); Mocker.GetMock<IRootFolderRepository>().Setup(c => c.All()).Returns(new List<RootFolder>());
const string path = "d:\\bad folder"; const string path = "d:\\bad folder";
@ -98,7 +95,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
[Test] [Test]
public void adding_duplicated_root_folder_should_throw() public void adding_duplicated_root_folder_should_throw()
{ {
Mocker.GetMock<IBasicRepository<RootFolder>>().Setup(c => c.All()).Returns(new List<RootFolder> { new RootFolder { Path = "C:\\TV".AsOsAgnostic() } }); Mocker.GetMock<IRootFolderRepository>().Setup(c => c.All()).Returns(new List<RootFolder> { new RootFolder { Path = "C:\\TV".AsOsAgnostic() } });
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() })); Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() }));
} }

@ -116,6 +116,8 @@ namespace NzbDrone.Core.Datastore
DataMapper.Insert(model); DataMapper.Insert(model);
ModelCreated(model);
return model; return model;
} }
@ -127,12 +129,15 @@ namespace NzbDrone.Core.Datastore
} }
DataMapper.Update(model, c => c.Id == model.Id); DataMapper.Update(model, c => c.Id == model.Id);
ModelUpdated(model);
return model; return model;
} }
public void Delete(TModel model) public void Delete(TModel model)
{ {
DataMapper.Delete<TModel>(c => c.Id == model.Id); Delete(model.Id);
} }
public void InsertMany(IList<TModel> models) public void InsertMany(IList<TModel> models)
@ -199,6 +204,8 @@ namespace NzbDrone.Core.Datastore
.ColumnsIncluding(properties) .ColumnsIncluding(properties)
.Entity(model) .Entity(model)
.Execute(); .Execute();
ModelUpdated(model);
} }
public virtual PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec) public virtual PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec)

@ -436,6 +436,7 @@
<Compile Include="Parser\Parser.cs" /> <Compile Include="Parser\Parser.cs" />
<Compile Include="Parser\ParsingService.cs" /> <Compile Include="Parser\ParsingService.cs" />
<Compile Include="Parser\QualityParser.cs" /> <Compile Include="Parser\QualityParser.cs" />
<Compile Include="RootFolders\RootFolderRepository.cs" />
<Compile Include="ThingiProvider\ConfigContractNotFoundException.cs" /> <Compile Include="ThingiProvider\ConfigContractNotFoundException.cs" />
<Compile Include="ThingiProvider\IProvider.cs" /> <Compile Include="ThingiProvider\IProvider.cs" />
<Compile Include="Qualities\QualityProfileInUseException.cs" /> <Compile Include="Qualities\QualityProfileInUseException.cs" />

@ -0,0 +1,27 @@
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.RootFolders
{
public interface IRootFolderRepository : IBasicRepository<RootFolder>
{
}
public class RootFolderRepository : BasicRepository<RootFolder>, IRootFolderRepository
{
public RootFolderRepository(IDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
}
protected override bool PublishModelEvents
{
get
{
return true;
}
}
}
}

@ -25,7 +25,7 @@ namespace NzbDrone.Core.RootFolders
public class RootFolderService : IRootFolderService public class RootFolderService : IRootFolderService
{ {
private static readonly Logger Logger = NzbDroneLogger.GetLogger(); private static readonly Logger Logger = NzbDroneLogger.GetLogger();
private readonly IBasicRepository<RootFolder> _rootFolderRepository; private readonly IRootFolderRepository _rootFolderRepository;
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly ISeriesRepository _seriesRepository; private readonly ISeriesRepository _seriesRepository;
private readonly IConfigService _configService; private readonly IConfigService _configService;
@ -33,7 +33,7 @@ namespace NzbDrone.Core.RootFolders
private static readonly HashSet<string> SpecialFolders = new HashSet<string> { "$recycle.bin", "system volume information", "recycler", "lost+found" }; private static readonly HashSet<string> SpecialFolders = new HashSet<string> { "$recycle.bin", "system volume information", "recycler", "lost+found" };
public RootFolderService(IBasicRepository<RootFolder> rootFolderRepository, public RootFolderService(IRootFolderRepository rootFolderRepository,
IDiskProvider diskProvider, IDiskProvider diskProvider,
ISeriesRepository seriesRepository, ISeriesRepository seriesRepository,
IConfigService configService) IConfigService configService)

@ -22,7 +22,6 @@ namespace NzbDrone.Host
AutoRegisterImplementations<NzbDronePersistentConnection>(); AutoRegisterImplementations<NzbDronePersistentConnection>();
Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>));
Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>)); Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>));
Container.Register<INancyBootstrapper, NancyBootstrapper>(); Container.Register<INancyBootstrapper, NancyBootstrapper>();

@ -1,4 +1,9 @@
using NLog; using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Transports;
using NLog;
using NLog.Config; using NLog.Config;
using NLog.Targets; using NLog.Targets;
using NUnit.Framework; using NUnit.Framework;
@ -7,7 +12,9 @@ using NzbDrone.Api.Config;
using NzbDrone.Api.History; using NzbDrone.Api.History;
using NzbDrone.Api.RootFolders; using NzbDrone.Api.RootFolders;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Serializer;
using NzbDrone.Integration.Test.Client; using NzbDrone.Integration.Test.Client;
using NzbDrone.SignalR;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
using NzbDrone.Test.Common.Categories; using NzbDrone.Test.Common.Categories;
using RestSharp; using RestSharp;
@ -30,6 +37,16 @@ namespace NzbDrone.Integration.Test
protected ClientBase<NamingConfigResource> NamingConfig; protected ClientBase<NamingConfigResource> NamingConfig;
private NzbDroneRunner _runner; private NzbDroneRunner _runner;
private List<SignalRMessage> _signalRReceived;
private Connection _signalrConnection;
protected IEnumerable<SignalRMessage> SignalRMessages
{
get
{
return _signalRReceived;
}
}
public IntegrationTest() public IntegrationTest()
{ {
@ -71,5 +88,48 @@ namespace NzbDrone.Integration.Test
{ {
_runner.KillAll(); _runner.KillAll();
} }
[TearDown]
public void IntegrationSetup()
{
if (_signalrConnection != null)
{
switch (_signalrConnection.State)
{
case ConnectionState.Connected:
case ConnectionState.Connecting:
{
_signalrConnection.Stop();
break;
}
}
_signalrConnection = null;
_signalRReceived = new List<SignalRMessage>();
}
}
protected void ConnectSignalR()
{
_signalRReceived = new List<SignalRMessage>();
_signalrConnection = new Connection("http://localhost:8989/signalr");
_signalrConnection.Start(new LongPollingTransport()).ContinueWith(task =>
{
if (task.IsFaulted)
{
Assert.Fail("SignalrConnection failed. {0}", task.Exception.GetBaseException());
}
});
while (_signalrConnection.State != ConnectionState.Connected)
{
Console.WriteLine("Connecting to signalR" + _signalrConnection.State);
Thread.Sleep(200);
}
_signalrConnection.Received += json => _signalRReceived.Add(Json.Deserialize<SignalRMessage>(json)); ;
}
} }
} }

@ -41,9 +41,9 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath> <HintPath>..\packages\FluentValidation.5.0.0.1\lib\Net40\FluentValidation.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.AspNet.SignalR.Client, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.AspNet.SignalR.Client, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.0.0\lib\net40\Microsoft.AspNet.SignalR.Client.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.SignalR.Client.1.1.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Owin, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Owin, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
@ -138,6 +138,10 @@
<Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project> <Project>{95C11A9E-56ED-456A-8447-2C89C1139266}</Project>
<Name>NzbDrone.Host</Name> <Name>NzbDrone.Host</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\NzbDrone.SignalR\NzbDrone.SignalR.csproj">
<Project>{7C2CC69F-5CA0-4E5C-85CB-983F9F6C3B36}</Project>
<Name>NzbDrone.SignalR</Name>
</ProjectReference>
<ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj"> <ProjectReference Include="..\NzbDrone.Test.Common\NzbDrone.Test.Common.csproj">
<Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project> <Project>{CADDFCE0-7509-4430-8364-2074E1EEFCA2}</Project>
<Name>NzbDrone.Test.Common</Name> <Name>NzbDrone.Test.Common</Name>

@ -1,8 +1,5 @@
using System; using System;
using System.Collections.Generic;
using FluentAssertions; using FluentAssertions;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Transports;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Api.RootFolders; using NzbDrone.Api.RootFolders;
@ -11,39 +8,25 @@ namespace NzbDrone.Integration.Test
[TestFixture] [TestFixture]
public class RootFolderIntegrationTest : IntegrationTest public class RootFolderIntegrationTest : IntegrationTest
{ {
private Connection _connection;
private List<object> _signalRReceived;
[SetUp]
public void Setup()
{
_signalRReceived = new List<object>();
_connection = new Connection("http://localhost:8989/signalr/rootfolder");
_connection.Start(new LongPollingTransport()).ContinueWith(task =>
{
if (task.IsFaulted)
{
Assert.Fail("SignalrConnection failed. {0}", task.Exception.GetBaseException());
}
});
_connection.Received += _connection_Received;
}
private void _connection_Received(string obj) [Test]
public void should_have_no_root_folder_initially()
{ {
_signalRReceived.Add(obj); RootFolders.All().Should().BeEmpty();
} }
[Test] [Test]
public void should_have_no_root_folder_initially() public void should_add_and_delete_root_folders()
{ {
RootFolders.All().Should().BeEmpty();
ConnectSignalR();
var rootFolder = new RootFolderResource var rootFolder = new RootFolderResource
{ {
Path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) Path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
}; };
var postResponse = RootFolders.Post(rootFolder); var postResponse = RootFolders.Post(rootFolder);
@ -56,6 +39,11 @@ namespace NzbDrone.Integration.Test
RootFolders.Delete(postResponse.Id); RootFolders.Delete(postResponse.Id);
RootFolders.All().Should().BeEmpty(); RootFolders.All().Should().BeEmpty();
SignalRMessages.Should().Contain(c => c.Name == "rootfolder");
} }
[Test] [Test]

@ -2,7 +2,7 @@
<packages> <packages>
<package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" /> <package id="FluentAssertions" version="2.1.0.0" targetFramework="net40" />
<package id="FluentValidation" version="5.0.0.1" targetFramework="net40" /> <package id="FluentValidation" version="5.0.0.1" targetFramework="net40" />
<package id="Microsoft.AspNet.SignalR.Client" version="2.0.0" targetFramework="net40" /> <package id="Microsoft.AspNet.SignalR.Client" version="1.1.3" targetFramework="net40" />
<package id="Microsoft.Owin" version="2.0.1" targetFramework="net40" /> <package id="Microsoft.Owin" version="2.0.1" targetFramework="net40" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.1" targetFramework="net40" /> <package id="Microsoft.Owin.Host.HttpListener" version="2.0.1" targetFramework="net40" />
<package id="Microsoft.Owin.Hosting" version="2.0.1" targetFramework="net40" /> <package id="Microsoft.Owin.Hosting" version="2.0.1" targetFramework="net40" />

Loading…
Cancel
Save