changeset 111:90ce239cfa6d

Tests sobre el publicador de twitter, cada track se pulica solo una vez
author Nelo@Kenia.neluz.int
date Wed, 08 Jun 2011 08:40:04 -0300
parents a456eb519e23
children 0bca45e1e664
files Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj Agendas/trunk/src/Agendas.Domain/Evento.cs Agendas/trunk/src/Agendas.Domain/Track.cs Agendas/trunk/src/Agendas.Domain/TrackLog.cs Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs Agendas/trunk/src/Agendas.Twitter.Tests/Agendas.Twitter.Tests.csproj Agendas/trunk/src/Agendas.Twitter.Tests/Publicador_tests.cs Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj Agendas/trunk/src/Agendas.Twitter/ITwitterAdapter.cs Agendas/trunk/src/Agendas.Twitter/TwitterPublicador.cs Agendas/trunk/src/Agendas.Twitter/oAuthTwitter.cs
diffstat 11 files changed, 220 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj	Wed Jun 08 08:40:04 2011 -0300
@@ -68,6 +68,7 @@
     <Compile Include="Services\PersonaService.cs" />
     <Compile Include="TipoEvento.cs" />
     <Compile Include="Track.cs" />
+    <Compile Include="TrackLog.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
--- a/Agendas/trunk/src/Agendas.Domain/Evento.cs	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/Evento.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -14,7 +14,7 @@
 		#region Propiedades del Evento
 
 		private readonly IList<Track> _tracks;
-		private readonly ICollection<Track> _newTracks = new List<Track>();
+		private ICollection<Track> _newTracks = new List<Track>();
 
 		/// <summary>
 		/// Título del evento
--- a/Agendas/trunk/src/Agendas.Domain/Track.cs	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/Track.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -1,13 +1,20 @@
-namespace AltNetHispano.Agendas.Domain
+using System;
+using System.Collections.Generic;
+
+namespace AltNetHispano.Agendas.Domain
 {
 	public class Track : Identificable
 	{
+		private readonly IList<TrackLog> _logs;
+
 		protected Track()
 		{
 			//ctor para NHibernate
+			_logs = new List<TrackLog>();
 		}
 
 		public Track(Evento evento, Accion accion)
+			: this()
 		{
 			Usuario = IdentityContext.GetUsuario();
 			Evento = evento;
@@ -17,6 +24,17 @@
 		public virtual Evento Evento { get; private set; }
 		public virtual Accion Accion { get; private set; }
 		public virtual Persona Usuario { get; private set; }
+
+		public virtual IEnumerable<TrackLog> Logs
+		{
+			get { return _logs; }
+		}
+
+		public virtual void LogAdd(TrackLog trackLog)
+		{
+			trackLog.Track = this;
+			_logs.Add(trackLog);
+		}
 	}
 
 	public enum Accion
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Domain/TrackLog.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -0,0 +1,26 @@
+namespace AltNetHispano.Agendas.Domain
+{
+	public class TrackLog : Identificable
+	{
+		protected TrackLog()
+		{
+		}
+
+		public TrackLog(TrackLogPropietario propietario, string mensaje)
+		{
+			Propietario = propietario;
+			Mensaje = mensaje;
+		}
+
+		public virtual TrackLogPropietario Propietario { get; set; }
+		public virtual string Mensaje { get; set; }
+		public virtual Track Track { get; set; }
+	}
+
+	public enum TrackLogPropietario
+	{
+		Twitter = 1
+	}
+
+
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -1,5 +1,4 @@
-using System;
-using AltNetHispano.Agendas.Domain;
+using AltNetHispano.Agendas.Domain;
 using ConfOrm;
 using ConfOrm.NH;
 using NHibernate;
@@ -21,6 +20,7 @@
 				orm.TablePerClass<Persona>();
 				orm.TablePerClass<Evento>();
 				orm.TablePerClass<Track>();
+				orm.TablePerClass<TrackLog>();
 				orm.TablePerClass<Cuenta>();
 
 				orm.Cascade<Evento, Persona>(Cascade.None);
--- a/Agendas/trunk/src/Agendas.Twitter.Tests/Agendas.Twitter.Tests.csproj	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Twitter.Tests/Agendas.Twitter.Tests.csproj	Wed Jun 08 08:40:04 2011 -0300
@@ -31,6 +31,9 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Moq">
+      <HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
+    </Reference>
     <Reference Include="Newtonsoft.Json">
       <HintPath>..\packages\Newtonsoft.Json.3.5.8\lib\35\Newtonsoft.Json.dll</HintPath>
     </Reference>
@@ -55,6 +58,7 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Publicador_tests.cs" />
     <Compile Include="Send_twitt_tests.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
@@ -67,6 +71,10 @@
       <Project>{A14907DF-02E4-4FA7-BE27-4292AF50AA22}</Project>
       <Name>Agendas.Domain</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Agendas.Tests\Agendas.Tests.csproj">
+      <Project>{29AC1253-D455-4958-9AAA-DA879C3889A4}</Project>
+      <Name>Agendas.Tests</Name>
+    </ProjectReference>
     <ProjectReference Include="..\Agendas.Twitter\Agendas.Twitter.csproj">
       <Project>{D8DA7ED2-A274-4DF6-9DD2-A9DC65F4C2F5}</Project>
       <Name>Agendas.Twitter</Name>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Twitter.Tests/Publicador_tests.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -0,0 +1,72 @@
+using System;
+using AltNetHispano.Agendas.Domain;
+using AltNetHispano.Agendas.Tests;
+using AltNetHispano.Agendas.Twitter;
+using Moq;
+using NUnit.Framework;
+using Twitterizer;
+
+namespace Agendas.Twitter.Tests
+{
+	[TestFixture]
+	public class Publicador_tests : TestBase
+	{
+		[Test]
+		public void Proponer_evento()
+		{
+			var adapter = new Mock<ITwitterAdapter>();
+			string twitt = null;
+
+			var response = new TwitterResponse<TwitterStatus>
+			               	{
+			               		Result =
+			               			RequestResult.Success
+			               	};
+
+			adapter.Setup(a => a.UpdateStatus(It.IsAny<OAuthTokens>(), It.IsAny<string>()))
+				.Returns(response)
+				.Callback<OAuthTokens, string>((tokens, status) => twitt = status);
+
+			var publicador = new TwitterPublicador(adapter.Object);
+
+			var agenda = new Agenda(publicador, DefaultEventoRepository, DefaultPersonaRepository);
+
+			agenda.Proponer("Identity Providers", null, null, TipoEvento.GrupoEstudio);
+
+			adapter.Verify(a => a.UpdateStatus(It.IsAny<OAuthTokens>(), It.IsAny<string>()), Times.Once());
+
+			Assert.That(twitt, Is.StringContaining("GrupoEstudio"));
+		}
+
+		[Test]
+		public void Proponer_y_agendar_evento()
+		{
+			var adapter = new Mock<ITwitterAdapter>();
+			string twitt = null;
+
+			var response = new TwitterResponse<TwitterStatus>
+			{
+				Result =
+					RequestResult.Success
+			};
+
+			adapter.Setup(a => a.UpdateStatus(It.IsAny<OAuthTokens>(), It.IsAny<string>()))
+				.Returns(response)
+				.Callback<OAuthTokens, string>((tokens, status) => twitt = status);
+
+			var publicador = new TwitterPublicador(adapter.Object);
+
+			var agenda = new Agenda(publicador, DefaultEventoRepository, DefaultPersonaRepository);
+			agenda.Proponer("Identity Providers", null, null, TipoEvento.GrupoEstudio);
+
+			adapter.Verify(a => a.UpdateStatus(It.IsAny<OAuthTokens>(), It.IsAny<string>()), Times.Once());
+
+			agenda.Agendar("Identity Providers", "Nelo Pauselli", DateTime.Today.AddDays(7), null, TipoEvento.GrupoEstudio);
+
+			adapter.Verify(a => a.UpdateStatus(It.IsAny<OAuthTokens>(), It.IsAny<string>()), Times.Exactly(2));
+
+			Assert.That(twitt, Is.StringContaining("@nelopauselli"));
+
+		}
+	}
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj	Wed Jun 08 08:40:04 2011 -0300
@@ -48,6 +48,7 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ITwitterAdapter.cs" />
     <Compile Include="OAuthTwitter.cs" />
     <Compile Include="TwitterPublicador.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Twitter/ITwitterAdapter.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -0,0 +1,54 @@
+using System;
+using Twitterizer;
+
+namespace AltNetHispano.Agendas.Twitter
+{
+	public interface ITwitterAdapter
+	{
+		Uri BuildAuthorizationUri(string consumerKey, string consumerSecret, string callbackAddress);
+		string GetAccessToken(string consumerKey, string consumerSecret, string requestToken, string verifier);
+		TwitterResponse<TwitterStatus> UpdateStatus(OAuthTokens tokens, string status);
+	}
+
+	public class TwitterAdapter : ITwitterAdapter
+	{
+		public Uri BuildAuthorizationUri(string consumerKey, string consumerSecret, string callbackAddress)
+		{
+			// Obtain a request token
+			OAuthTokenResponse requestToken = OAuthUtility.GetRequestToken(consumerKey, consumerSecret, callbackAddress);
+			
+			// Direct or instruct the user to the following address:
+			Uri authorizationUri = OAuthUtility.BuildAuthorizationUri(requestToken.Token);
+
+			return authorizationUri;
+		}
+
+		public string GetAccessToken(string consumerKey, string consumerSecret, string requestToken, string verifier)
+		{
+			OAuthTokenResponse accessToken = OAuthUtility.GetAccessToken(consumerKey, consumerSecret, requestToken, verifier);
+
+			if (accessToken != null)
+			{
+				var tokens = new OAuthTokens
+				{
+					AccessToken = accessToken.Token,
+					AccessTokenSecret = accessToken.TokenSecret,
+					ConsumerKey = consumerKey,
+					ConsumerSecret = consumerSecret
+				};
+
+				TwitterResponse<TwitterUser> showUserResponse = TwitterUser.Show(tokens, accessToken.UserId);
+				if (showUserResponse.Result == RequestResult.Success)
+					return showUserResponse.Content;
+				return showUserResponse.ErrorMessage;
+			}
+			return string.Empty;
+
+		}
+
+		public TwitterResponse<TwitterStatus> UpdateStatus(OAuthTokens tokens, string status)
+		{
+			return TwitterStatus.Update(tokens, status);
+		}
+	}
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Twitter/TwitterPublicador.cs	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Twitter/TwitterPublicador.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -1,5 +1,6 @@
 using System.Collections.Generic;
 using System.Configuration;
+using System.Linq;
 using AltNetHispano.Agendas.Domain;
 using Twitterizer;
 
@@ -7,6 +8,18 @@
 {
 	public class TwitterPublicador : IPublicador
 	{
+		private readonly ITwitterAdapter _twitterAdapter;
+
+		public TwitterPublicador()
+		{
+			_twitterAdapter = new TwitterAdapter();
+		}
+
+		public TwitterPublicador(ITwitterAdapter twitterAdapter)
+		{
+			_twitterAdapter = twitterAdapter;
+		}
+
 		public const int LIMITE_MENSAJE = 140;
 
 		private string ConsumerKey
@@ -35,10 +48,16 @@
 		{
 			foreach (var track in tracks)
 			{
-				string message;
+				//Si ya hicimos el twitt de este track, no volvemos a hacerlo
+				if (track.Logs.Any(l => l.Propietario == TrackLogPropietario.Twitter)) continue;
+
 				var twitt = BuildTwitt(track);
 				if (!string.IsNullOrWhiteSpace(twitt))
+				{
+					string message;
 					Publicar(twitt, out message);
+					track.LogAdd(new TrackLog(TrackLogPropietario.Twitter, message));
+				}
 			}
 		}
 
@@ -74,7 +93,7 @@
 								AccessTokenSecret = AccessTokenSecret
 							};
 
-			var response = TwitterStatus.Update(tokens, status);
+			var response = _twitterAdapter.UpdateStatus(tokens, status);
 
 			message = response.ErrorMessage;
 			return response.Result == RequestResult.Success;
--- a/Agendas/trunk/src/Agendas.Twitter/oAuthTwitter.cs	Wed Jun 08 07:33:14 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Twitter/oAuthTwitter.cs	Wed Jun 08 08:40:04 2011 -0300
@@ -1,11 +1,22 @@
 using System;
 using System.Configuration;
-using Twitterizer;
 
 namespace AltNetHispano.Agendas.Twitter
 {
 	public class OAuthTwitter
 	{
+		private readonly ITwitterAdapter _twitterAdapter;
+
+		public OAuthTwitter()
+		{
+			_twitterAdapter = new TwitterAdapter();
+		}
+
+		public OAuthTwitter(ITwitterAdapter twitterAdapter)
+		{
+			_twitterAdapter = twitterAdapter;
+		}
+
 		private string ConsumerKey
 		{
 			get { return ConfigurationManager.AppSettings["consumerKeyAppSignIn"]; }
@@ -18,35 +29,13 @@
 
 		public Uri AuthorizationLinkGet(string callbackAddress)
 		{
-			// Obtain a request token
-			OAuthTokenResponse requestToken = OAuthUtility.GetRequestToken(ConsumerKey, ConsumerSecret, callbackAddress);
-
-			// Direct or instruct the user to the following address:
-			Uri authorizationUri = OAuthUtility.BuildAuthorizationUri(requestToken.Token);
-
-			return authorizationUri;
+			var request = _twitterAdapter.BuildAuthorizationUri(ConsumerKey, ConsumerSecret, callbackAddress);
+			return request;
 		}
 
 		public string AccessTokenGet(string requestToken, string verifier)
 		{
-			OAuthTokenResponse accessToken = OAuthUtility.GetAccessToken(ConsumerKey, ConsumerSecret, requestToken, verifier);
-			
-			if (accessToken!=null)
-			{
-				var tokens = new OAuthTokens
-				             	{
-				             		AccessToken = accessToken.Token,
-				             		AccessTokenSecret = accessToken.TokenSecret,
-				             		ConsumerKey = ConsumerKey,
-				             		ConsumerSecret = ConsumerSecret
-				             	};
-
-				TwitterResponse<TwitterUser> showUserResponse = TwitterUser.Show(tokens, accessToken.UserId);
-				if (showUserResponse.Result == RequestResult.Success)
-					return showUserResponse.Content;
-				return showUserResponse.ErrorMessage;
-			}
-			return string.Empty;
+			return _twitterAdapter.GetAccessToken(ConsumerKey, ConsumerSecret, requestToken, verifier);
 		}
 	}
 }