issue 1 fix - added validation to prevent repeat tracking of a ticker within a portfolio (thanks correl)

This commit is contained in:
mgroves 2011-04-07 22:57:38 -04:00
parent 136e7c0a99
commit cc105decef
7 changed files with 64 additions and 7 deletions

View file

@ -115,6 +115,15 @@ namespace MonoStockPortfolio.Core.PortfolioRepositories
return position;
}
public bool IsTickerAlreadyBeingTracked(string ticker, long portfolioId)
{
var cursor = Db.RawQuery("SELECT 1 FROM " + POSITION_TABLE_NAME + " WHERE Ticker = ? AND ContainingPortfolioID = ?",
new[] { ticker, portfolioId.ToString() });
var result = cursor.Count > 0;
if(!cursor.IsClosed) cursor.Close();
return result;
}
public IList<Position> GetAllPositions(long portfolioId)
{
var list = new List<Position>();

View file

@ -15,5 +15,6 @@ namespace MonoStockPortfolio.Core.PortfolioRepositories
void SavePosition(Position position);
void DeletePositionById(long positionId);
Position GetPositionById(long positionId);
bool IsTickerAlreadyBeingTracked(string ticker, long portfolioId);
}
}

View file

@ -66,6 +66,7 @@
<Compile Include="Presenters\Config\Given_an_initialized_Config_Presenter.cs" />
<Compile Include="Presenters\EditPortfolio\EditPortfolioTests.cs" />
<Compile Include="Presenters\EditPosition\EditPositionTests.cs" />
<Compile Include="Presenters\EditPosition\When_the_user_tries_to_save_a_position_for_a_ticker_thats_already_being_tracked.cs" />
<Compile Include="Presenters\Main\MainPresenterTests.cs" />
<Compile Include="Presenters\Portfolio\PortfolioPresenterTests.cs" />
<Compile Include="Presenters\Portfolio\When_done_initializing_a_Portfolio_Presenter.cs" />

View file

@ -1,3 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Machine.Specifications;
using MonoStockPortfolio.Activites.EditPositionScreen;
using MonoStockPortfolio.Core.PortfolioRepositories;
@ -22,5 +25,9 @@ namespace MonoStockPortfolio.Tests.Presenters.EditPosition
_presenter = new EditPositionPresenter(_mockPortfolioRepository, _mockStockService);
};
protected static void MockPositionMatches(Expression<Predicate<IList<string>>> match)
{
Mock.Assert(() => _mockView.ShowErrorMessages(Arg.Matches(match)), Occurs.Exactly(1));
}
}
}

View file

@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
using Machine.Specifications;
using MonoStockPortfolio.Activites.EditPositionScreen;
using MonoStockPortfolio.Entities;
using Telerik.JustMock;
namespace MonoStockPortfolio.Tests.Presenters.EditPosition
{
[Tags("UnitTest")]
public class When_the_user_tries_to_save_a_position_for_a_ticker_thats_already_being_tracked : EditPositionTests
{
Establish context = () =>
{
_presenter.Initialize(_mockView, 1);
Mock.Arrange(() => _mockStockService.IsValidTicker(Arg.AnyString)).Returns(true);
Mock.Arrange(() => _mockPortfolioRepository.IsTickerAlreadyBeingTracked(Arg.AnyString, Arg.AnyLong)).Returns(true);
};
Because of = () =>
{
var fakeInputModel = new PositionInputModel { PriceText = "5", SharesText = "5", TickerText = "ABC" };
_presenter.Save(fakeInputModel);
};
It should_not_try_to_save_the_portfolio = () =>
Mock.Assert(() => _mockPortfolioRepository.SavePosition(Arg.IsAny<Position>()), Occurs.Never());
It should_send_the_validation_errors_to_the_view = () =>
Mock.Assert(() => _mockView.ShowErrorMessages(Arg.IsAny<IList<string>>()), Occurs.Exactly(1));
It should_send_a_duplicate_ticker_error_to_the_view = () =>
MockPositionMatches(x => x.Any(p => p == "You are already tracking that ticker in this portfolio"));
}
}

View file

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Machine.Specifications;
using MonoStockPortfolio.Activites.EditPositionScreen;
using MonoStockPortfolio.Entities;
@ -37,10 +36,5 @@ namespace MonoStockPortfolio.Tests.Presenters.EditPosition
MockPositionMatches(x => x.Any(p => p == "Please enter a valid, positive price per share"));
It should_not_tell_the_view_to_go_back_to_the_main_activity = () =>
Mock.Assert(() => _mockView.GoBackToPortfolioActivity(), Occurs.Never());
private static void MockPositionMatches(Expression<Predicate<IList<string>>> match)
{
Mock.Assert(() => _mockView.ShowErrorMessages(Arg.Matches(match)), Occurs.Exactly(1));
}
}
}

View file

@ -1,3 +1,4 @@
using System;
using System.Linq;
using Android.Runtime;
using Android.Util;
@ -48,6 +49,7 @@ namespace MonoStockPortfolio.Activites.EditPositionScreen
validator.AddValidPositiveDecimal(() => positionInputModel.SharesText, "Please enter a valid, positive number of shares");
validator.AddValidPositiveDecimal(() => positionInputModel.PriceText, "Please enter a valid, positive price per share");
validator.AddValidation(() => ValidateTicker(positionInputModel.TickerText));
validator.AddValidation(() => ValidateNotRepeatTicker(positionInputModel.TickerText));
var errorMessages = validator.Apply();
if (!errorMessages.Any())
@ -87,6 +89,15 @@ namespace MonoStockPortfolio.Activites.EditPositionScreen
return string.Empty;
}
return "Invalid Ticker Name";
}
}
private string ValidateNotRepeatTicker(string ticker)
{
if(_portfolioRepository.IsTickerAlreadyBeingTracked(ticker, _portfolioId))
{
return "You are already tracking that ticker in this portfolio";
}
return string.Empty;
}
}
}