Created notifications repository and service with unit tests, then need to start integrating that so notifications are properly sent.

This commit is contained in:
Shannon
2014-01-10 17:03:00 +11:00
parent 4346f73159
commit 531306a091
9 changed files with 428 additions and 1 deletions

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Umbraco.Core.Models
{
internal class Notification
{
public Notification(int entityId, int userId, string action, Guid entityType)
{
EntityId = entityId;
UserId = userId;
Action = action;
EntityType = entityType;
}
public int EntityId { get; private set; }
public int UserId { get; private set; }
public string Action { get; private set; }
public Guid EntityType { get; private set; }
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class NotificationsRepository
{
private readonly IDatabaseUnitOfWork _unitOfWork;
public NotificationsRepository(IDatabaseUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public IEnumerable<Notification> GetUserNotifications(IUser user)
{
var sql = new Sql()
.Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action")
.From<User2NodeNotifyDto>()
.InnerJoin<NodeDto>()
.On<User2NodeNotifyDto, NodeDto>(dto => dto.NodeId, dto => dto.NodeId)
.Where<User2NodeNotifyDto>(dto => dto.UserId == (int)user.Id)
.OrderBy<NodeDto>(dto => dto.NodeId);
var dtos = _unitOfWork.Database.Fetch<dynamic>(sql);
//need to map the results
return dtos.Select(d => new Notification(d.id, d.userId, d.action, d.nodeObjectType)).ToList();
}
public IEnumerable<Notification> GetEntityNotifications(IEntity entity)
{
var sql = new Sql()
.Select("DISTINCT umbracoNode.id, umbracoUser2NodeNotify.userId, umbracoNode.nodeObjectType, umbracoUser2NodeNotify.action")
.From<User2NodeNotifyDto>()
.InnerJoin<NodeDto>()
.On<User2NodeNotifyDto, NodeDto>(dto => dto.NodeId, dto => dto.NodeId)
.Where<User2NodeNotifyDto>(dto => dto.NodeId == entity.Id)
.OrderBy<NodeDto>(dto => dto.NodeId);
var dtos = _unitOfWork.Database.Fetch<dynamic>(sql);
//need to map the results
return dtos.Select(d => new Notification(d.id, d.userId, d.action, d.nodeObjectType)).ToList();
}
public int DeleteNotifications(IEntity entity)
{
return _unitOfWork.Database.Delete<User2NodeNotifyDto>("WHERE nodeId = @nodeId", new { nodeId = entity.Id });
}
public int DeleteNotifications(IUser user)
{
return _unitOfWork.Database.Delete<User2NodeNotifyDto>("WHERE userId = @userId", new { userId = user.Id });
}
public int DeleteNotifications(IUser user, IEntity entity)
{
// delete all settings on the node for this user
return _unitOfWork.Database.Delete<User2NodeNotifyDto>("WHERE userId = @userId AND nodeId = @nodeId", new { userId = user.Id, nodeId = entity.Id });
}
public Notification CreateNotification(IUser user, IEntity entity, string action)
{
var sql = new Sql()
.Select("DISTINCT nodeObjectType")
.From<NodeDto>()
.Where<NodeDto>(nodeDto => nodeDto.NodeId == entity.Id);
var nodeType = _unitOfWork.Database.ExecuteScalar<Guid>(sql);
var dto = new User2NodeNotifyDto()
{
Action = action,
NodeId = entity.Id,
UserId = (int)user.Id
};
_unitOfWork.Database.Insert(dto);
return new Notification(dto.NodeId, dto.UserId, dto.Action, nodeType);
}
}
}

View File

@@ -0,0 +1,66 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using umbraco.interfaces;
namespace Umbraco.Core.Services
{
internal interface INotificationService : IService
{
/// <summary>
/// Sends the notifications for the specified user regarding the specified node and action.
/// </summary>
/// <param name="entity"></param>
/// <param name="user"></param>
/// <param name="action"></param>
void SendNotifications(IEntity entity, IUser user, IAction action);
/// <summary>
/// Gets the notifications for the user
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
IEnumerable<Notification> GetUserNotifications(IUser user);
/// <summary>
/// Returns the notifications for an entity
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
IEnumerable<Notification> GetEntityNotifications(IEntity entity);
/// <summary>
/// Deletes notifications by entity
/// </summary>
/// <param name="entity"></param>
void DeleteNotifications(IEntity entity);
/// <summary>
/// Deletes notifications by user
/// </summary>
/// <param name="user"></param>
void DeleteNotifications(IUser user);
/// <summary>
/// Delete notifications by user and entity
/// </summary>
/// <param name="user"></param>
/// <param name="entity"></param>
void DeleteNotifications(IUser user, IEntity entity);
/// <summary>
/// Creates a new notification
/// </summary>
/// <param name="user"></param>
/// <param name="entity"></param>
/// <param name="action">The action letter - note: this is a string for future compatibility</param>
/// <returns></returns>
Notification CreateNotification(IUser user, IEntity entity, string action);
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using umbraco.interfaces;
namespace Umbraco.Core.Services
{
internal class NotificationService : INotificationService
{
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
public NotificationService(IDatabaseUnitOfWorkProvider provider)
{
_uowProvider = provider;
}
/// <summary>
/// Sends the notifications for the specified user regarding the specified node and action.
/// </summary>
/// <param name="entity"></param>
/// <param name="user"></param>
/// <param name="action"></param>
public void SendNotifications(IEntity entity, IUser user, IAction action)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets the notifications for the user
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public IEnumerable<Notification> GetUserNotifications(IUser user)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
return repository.GetUserNotifications(user);
}
/// <summary>
/// Deletes notifications by entity
/// </summary>
/// <param name="entity"></param>
public IEnumerable<Notification> GetEntityNotifications(IEntity entity)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
return repository.GetEntityNotifications(entity);
}
/// <summary>
/// Deletes notifications by entity
/// </summary>
/// <param name="entity"></param>
public void DeleteNotifications(IEntity entity)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
repository.DeleteNotifications(entity);
}
/// <summary>
/// Deletes notifications by user
/// </summary>
/// <param name="user"></param>
public void DeleteNotifications(IUser user)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
repository.DeleteNotifications(user);
}
/// <summary>
/// Delete notifications by user and entity
/// </summary>
/// <param name="user"></param>
/// <param name="entity"></param>
public void DeleteNotifications(IUser user, IEntity entity)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
repository.DeleteNotifications(user, entity);
}
/// <summary>
/// Creates a new notification
/// </summary>
/// <param name="user"></param>
/// <param name="entity"></param>
/// <param name="action">The action letter - note: this is a string for future compatibility</param>
/// <returns></returns>
public Notification CreateNotification(IUser user, IEntity entity, string action)
{
var uow = _uowProvider.GetUnitOfWork();
var repository = new NotificationsRepository(uow);
return repository.CreateNotification(user, entity, action);
}
}
}

View File

@@ -192,6 +192,7 @@
<Compile Include="Models\IRelation.cs" />
<Compile Include="Models\IRelationType.cs" />
<Compile Include="Models\Membership\EntityPermission.cs" />
<Compile Include="Models\Notification.cs" />
<Compile Include="Models\PreValue.cs" />
<Compile Include="Models\PreValueCollection.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentExtended.cs" />
@@ -205,6 +206,7 @@
<Compile Include="Persistence\Querying\StringPropertyMatchType.cs" />
<Compile Include="Persistence\Querying\TextColumnType.cs" />
<Compile Include="Persistence\Querying\ValuePropertyMatchType.cs" />
<Compile Include="Persistence\Repositories\NotificationsRepository.cs" />
<Compile Include="Persistence\SqlSyntax\MySqlSyntax.cs" />
<Compile Include="Persistence\SqlSyntax\SqlCeSyntax.cs" />
<Compile Include="Persistence\SqlSyntax\SqlServerSyntax.cs" />
@@ -768,6 +770,7 @@
<Compile Include="Services\IMembershipMemberService.cs" />
<Compile Include="Services\IMembershipUserService.cs" />
<Compile Include="Services\IMemberTypeService.cs" />
<Compile Include="Services\INotificationService.cs" />
<Compile Include="Services\IRelationService.cs" />
<Compile Include="Services\IService.cs" />
<Compile Include="Services\IUserService.cs" />
@@ -776,6 +779,7 @@
<Compile Include="Services\MemberCountType.cs" />
<Compile Include="Services\MemberService.cs" />
<Compile Include="Services\MemberTypeService.cs" />
<Compile Include="Services\NotificationService.cs" />
<Compile Include="Services\RelationService.cs" />
<Compile Include="Services\ServerRegistrationService.cs" />
<Compile Include="Services\PackagingService.cs" />

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;

View File

@@ -0,0 +1,145 @@
using System;
using System.Globalization;
using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Persistence.Repositories
{
[TestFixture]
public class NotificationsRepositoryTest : BaseDatabaseFactoryTest
{
[Test]
public void CreateNotification()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repo = new NotificationsRepository(unitOfWork);
var node = new NodeDto {CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,123", SortOrder = 1, Text = "hello", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0};
var result = unitOfWork.Database.Insert(node);
var entity = Mock.Of<IEntity>(e => e.Id == node.NodeId);
var user = Mock.Of<IUser>(e => e.Id == (object)node.UserId);
var notification = repo.CreateNotification(user, entity, "A");
Assert.AreEqual("A", notification.Action);
Assert.AreEqual(node.NodeId, notification.EntityId);
Assert.AreEqual(node.NodeObjectType, notification.EntityType);
Assert.AreEqual(node.UserId, notification.UserId);
}
[Test]
public void GetUserNotifications()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repo = new NotificationsRepository(unitOfWork);
var userDto = new UserDto { ContentStartId = -1, DefaultPermissions = "", Email = "test" , Login = "test" , MediaStartId = -1, Password = "test" , Type = 1, UserName = "test" , UserLanguage = "en" };
unitOfWork.Database.Insert(userDto);
var userNew = Mock.Of<IUser>(e => e.Id == (object)userDto.Id);
var userAdmin = Mock.Of<IUser>(e => e.Id == (object)0);
for (var i = 0; i < 10; i++)
{
var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
var result = unitOfWork.Database.Insert(node);
var entity = Mock.Of<IEntity>(e => e.Id == node.NodeId);
var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
}
var notifications = repo.GetUserNotifications(userAdmin);
Assert.AreEqual(5, notifications.Count());
}
[Test]
public void GetEntityNotifications()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repo = new NotificationsRepository(unitOfWork);
var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
unitOfWork.Database.Insert(node1);
var entity1 = Mock.Of<IEntity>(e => e.Id == node1.NodeId);
var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
unitOfWork.Database.Insert(node2);
var entity2 = Mock.Of<IEntity>(e => e.Id == node2.NodeId);
for (var i = 0; i < 10; i++)
{
var userDto = new UserDto { ContentStartId = -1, DefaultPermissions = "", Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
unitOfWork.Database.Insert(userDto);
var userNew = Mock.Of<IUser>(e => e.Id == (object)userDto.Id);
var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
}
var notifications = repo.GetEntityNotifications(entity1);
Assert.AreEqual(5, notifications.Count());
}
[Test]
public void Delete_By_Entity()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repo = new NotificationsRepository(unitOfWork);
var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
unitOfWork.Database.Insert(node1);
var entity1 = Mock.Of<IEntity>(e => e.Id == node1.NodeId);
var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
unitOfWork.Database.Insert(node2);
var entity2 = Mock.Of<IEntity>(e => e.Id == node2.NodeId);
for (var i = 0; i < 10; i++)
{
var userDto = new UserDto { ContentStartId = -1, DefaultPermissions = "", Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
unitOfWork.Database.Insert(userDto);
var userNew = Mock.Of<IUser>(e => e.Id == (object)userDto.Id);
var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
}
var delCount = repo.DeleteNotifications(entity1);
Assert.AreEqual(5, delCount);
}
[Test]
public void Delete_By_User()
{
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repo = new NotificationsRepository(unitOfWork);
var userDto = new UserDto { ContentStartId = -1, DefaultPermissions = "", Email = "test", Login = "test", MediaStartId = -1, Password = "test", Type = 1, UserName = "test", UserLanguage = "en" };
unitOfWork.Database.Insert(userDto);
var userNew = Mock.Of<IUser>(e => e.Id == (object)userDto.Id);
var userAdmin = Mock.Of<IUser>(e => e.Id == (object)0);
for (var i = 0; i < 10; i++)
{
var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
var result = unitOfWork.Database.Insert(node);
var entity = Mock.Of<IEntity>(e => e.Id == node.NodeId);
var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
}
var delCount = repo.DeleteNotifications(userAdmin);
Assert.AreEqual(5, delCount);
}
}
}

View File

@@ -210,6 +210,7 @@
<Compile Include="Persistence\PetaPocoExtensionsTest.cs" />
<Compile Include="Persistence\Repositories\MemberRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\MemberTypeRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\NotificationsRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\TemplateRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\UserRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\UserTypeRepositoryTest.cs" />

View File

@@ -21,6 +21,7 @@ using umbraco.cms.businesslogic.workflow;
using umbraco.cms.businesslogic.Tags;
using File = System.IO.File;
using Media = umbraco.cms.businesslogic.media.Media;
using Notification = umbraco.cms.businesslogic.workflow.Notification;
using Task = umbraco.cms.businesslogic.task.Task;
namespace umbraco.cms.businesslogic