1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-04 10:02:40 +01:00

Fixed: Don’t allow profiles in use by lists to be deleted (#2797)

This commit is contained in:
Qstick 2018-05-21 04:32:20 -04:00 committed by Leonardo Galli
parent c1d2ea44b3
commit f058b8f364
3 changed files with 54 additions and 9 deletions

View File

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -6,6 +6,7 @@
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.NetImport;
namespace NzbDrone.Core.Test.Profiles namespace NzbDrone.Core.Test.Profiles
{ {
@ -46,8 +47,35 @@ public void should_not_be_able_to_delete_profile_if_assigned_to_movie()
.With(c => c.ProfileId = 2) .With(c => c.ProfileId = 2)
.Build().ToList(); .Build().ToList();
var netImportList = Builder<NetImportDefinition>.CreateListOfSize(3)
.All()
.With(c => c.ProfileId = 1)
.Build().ToList();
Mocker.GetMock<IMovieService>().Setup(c => c.GetAllMovies()).Returns(movieList); Mocker.GetMock<IMovieService>().Setup(c => c.GetAllMovies()).Returns(movieList);
Mocker.GetMock<INetImportFactory>().Setup(c => c.All()).Returns(netImportList);
Assert.Throws<ProfileInUseException>(() => Subject.Delete(2));
Mocker.GetMock<IProfileRepository>().Verify(c => c.Delete(It.IsAny<int>()), Times.Never());
}
[Test]
public void should_not_be_able_to_delete_profile_if_assigned_to_list()
{
var movieList = Builder<Movie>.CreateListOfSize(3)
.All()
.With(c => c.ProfileId = 1)
.Build().ToList();
var netImportList = Builder<NetImportDefinition>.CreateListOfSize(3)
.Random(1)
.With(c => c.ProfileId = 2)
.Build().ToList();
Mocker.GetMock<IMovieService>().Setup(c => c.GetAllMovies()).Returns(movieList);
Mocker.GetMock<INetImportFactory>().Setup(c => c.All()).Returns(netImportList);
Assert.Throws<ProfileInUseException>(() => Subject.Delete(2)); Assert.Throws<ProfileInUseException>(() => Subject.Delete(2));
@ -57,19 +85,24 @@ public void should_not_be_able_to_delete_profile_if_assigned_to_movie()
[Test] [Test]
public void should_delete_profile_if_not_assigned_to_movie() public void should_delete_profile_if_not_assigned_to_movie_or_list()
{ {
var movieList = Builder<Movie>.CreateListOfSize(3) var movieList = Builder<Movie>.CreateListOfSize(3)
.All() .All()
.With(c => c.ProfileId = 2) .With(c => c.ProfileId = 2)
.Build().ToList(); .Build().ToList();
var netImportList = Builder<NetImportDefinition>.CreateListOfSize(3)
.All()
.With(c => c.ProfileId = 2)
.Build().ToList();
Mocker.GetMock<IMovieService>().Setup(c => c.GetAllMovies()).Returns(movieList); Mocker.GetMock<IMovieService>().Setup(c => c.GetAllMovies()).Returns(movieList);
Mocker.GetMock<INetImportFactory>().Setup(c => c.All()).Returns(netImportList);
Subject.Delete(1); Subject.Delete(1);
Mocker.GetMock<IProfileRepository>().Verify(c => c.Delete(1), Times.Once()); Mocker.GetMock<IProfileRepository>().Verify(c => c.Delete(1), Times.Once());
} }
} }
} }

View File

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Lifecycle;
@ -6,6 +6,7 @@
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.NetImport;
namespace NzbDrone.Core.Profiles namespace NzbDrone.Core.Profiles
{ {
@ -23,12 +24,14 @@ public class ProfileService : IProfileService, IHandle<ApplicationStartedEvent>
{ {
private readonly IProfileRepository _profileRepository; private readonly IProfileRepository _profileRepository;
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly INetImportFactory _netImportFactory;
private readonly Logger _logger; private readonly Logger _logger;
public ProfileService(IProfileRepository profileRepository, IMovieService movieService, Logger logger) public ProfileService(IProfileRepository profileRepository, IMovieService movieService, INetImportFactory netImportFactory, Logger logger)
{ {
_profileRepository = profileRepository; _profileRepository = profileRepository;
_movieService = movieService; _movieService = movieService;
_netImportFactory = netImportFactory;
_logger = logger; _logger = logger;
} }
@ -44,7 +47,7 @@ public void Update(Profile profile)
public void Delete(int id) public void Delete(int id)
{ {
if (_movieService.GetAllMovies().Any(c => c.ProfileId == id)) if (_movieService.GetAllMovies().Any(c => c.ProfileId == id) || _netImportFactory.All().Any(c => c.ProfileId == id))
{ {
throw new ProfileInUseException(id); throw new ProfileInUseException(id);
} }
@ -153,4 +156,4 @@ public void Handle(ApplicationStartedEvent message)
); );
} }
} }
} }

View File

@ -8,6 +8,7 @@ var QualitySortableCollectionView = require('./QualitySortableCollectionView');
var EditProfileView = require('./EditProfileView'); var EditProfileView = require('./EditProfileView');
var DeleteView = require('../DeleteProfileView'); var DeleteView = require('../DeleteProfileView');
var FullMovieCollection = require('../../../Movies/FullMovieCollection'); var FullMovieCollection = require('../../../Movies/FullMovieCollection');
var NetImportCollection = require('../../NetImport/NetImportCollection');
var Config = require('../../../Config'); var Config = require('../../../Config');
var AsEditModalView = require('../../../Mixins/AsEditModalView'); var AsEditModalView = require('../../../Mixins/AsEditModalView');
@ -28,7 +29,10 @@ var view = Marionette.Layout.extend({
initialize : function(options) { initialize : function(options) {
this.profileCollection = options.profileCollection; this.profileCollection = options.profileCollection;
this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse()); this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse());
this.netImportCollection = new NetImportCollection;
this.netImportCollection.fetch();
this.listenTo(FullMovieCollection, 'all', this._updateDisableStatus); this.listenTo(FullMovieCollection, 'all', this._updateDisableStatus);
this.listenTo(this.netImportCollection, 'all', this._updateDisableStatus);
}, },
onRender : function() { onRender : function() {
@ -102,9 +106,10 @@ var view = Marionette.Layout.extend({
}, },
_updateDisableStatus : function() { _updateDisableStatus : function() {
if (this._isQualityInUse()) { if (this._isQualityInUse() || this._isQualityInUsebyList()) {
this.ui.deleteButton.attr('disabled', 'disabled');
this.ui.deleteButton.addClass('disabled'); this.ui.deleteButton.addClass('disabled');
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a movie.'); this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a movie or list.');
} else { } else {
this.ui.deleteButton.removeClass('disabled'); this.ui.deleteButton.removeClass('disabled');
} }
@ -112,6 +117,10 @@ var view = Marionette.Layout.extend({
_isQualityInUse : function() { _isQualityInUse : function() {
return FullMovieCollection.where({ 'profileId' : this.model.id }).length !== 0; return FullMovieCollection.where({ 'profileId' : this.model.id }).length !== 0;
},
_isQualityInUsebyList : function() {
return this.netImportCollection.where({ 'profileId' : this.model.id }).length !== 0;
} }
}); });
module.exports = AsEditModalView.call(view); module.exports = AsEditModalView.call(view);