mirror of
https://github.com/bitwarden/server
synced 2025-12-15 07:43:54 +00:00
PM-10564: Push notification updates to other clients
When a notification is updated, marked as read or deleted, a push notification is sent with updated push type event. The push notification includes the ReadDate and DeletedDate fields.
This commit is contained in:
@@ -26,5 +26,6 @@ public enum PushType : byte
|
|||||||
|
|
||||||
SyncOrganizations = 17,
|
SyncOrganizations = 17,
|
||||||
|
|
||||||
SyncNotification = 18,
|
SyncNotificationCreate = 18,
|
||||||
|
SyncNotificationUpdate = 19
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
using Bit.Core.Enums;
|
#nullable enable
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
|
||||||
namespace Bit.Core.Models;
|
namespace Bit.Core.Models;
|
||||||
|
|
||||||
public class PushNotificationData<T>
|
public class PushNotificationData<T>
|
||||||
{
|
{
|
||||||
public PushNotificationData(PushType type, T payload, string contextId)
|
public PushNotificationData(PushType type, T payload, string? contextId)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
Payload = payload;
|
Payload = payload;
|
||||||
@@ -13,7 +14,7 @@ public class PushNotificationData<T>
|
|||||||
|
|
||||||
public PushType Type { get; set; }
|
public PushType Type { get; set; }
|
||||||
public T Payload { get; set; }
|
public T Payload { get; set; }
|
||||||
public string ContextId { get; set; }
|
public string? ContextId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SyncCipherPushNotification
|
public class SyncCipherPushNotification
|
||||||
@@ -21,7 +22,7 @@ public class SyncCipherPushNotification
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid? UserId { get; set; }
|
public Guid? UserId { get; set; }
|
||||||
public Guid? OrganizationId { get; set; }
|
public Guid? OrganizationId { get; set; }
|
||||||
public IEnumerable<Guid> CollectionIds { get; set; }
|
public IEnumerable<Guid>? CollectionIds { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +53,8 @@ public class SyncNotificationPushNotification
|
|||||||
public Guid? OrganizationId { get; set; }
|
public Guid? OrganizationId { get; set; }
|
||||||
public ClientType ClientType { get; set; }
|
public ClientType ClientType { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
|
public DateTime? ReadDate { get; set; }
|
||||||
|
public DateTime? DeletedDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AuthRequestPushNotification
|
public class AuthRequestPushNotification
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class CreateNotificationCommand : ICreateNotificationCommand
|
|||||||
|
|
||||||
var newNotification = await _notificationRepository.CreateAsync(notification);
|
var newNotification = await _notificationRepository.CreateAsync(notification);
|
||||||
|
|
||||||
await _pushNotificationService.PushSyncNotificationAsync(newNotification);
|
await _pushNotificationService.PushSyncNotificationCreateAsync(newNotification, null);
|
||||||
|
|
||||||
return newNotification;
|
return newNotification;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@@ -16,16 +17,19 @@ public class CreateNotificationStatusCommand : ICreateNotificationStatusCommand
|
|||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly INotificationRepository _notificationRepository;
|
private readonly INotificationRepository _notificationRepository;
|
||||||
private readonly INotificationStatusRepository _notificationStatusRepository;
|
private readonly INotificationStatusRepository _notificationStatusRepository;
|
||||||
|
private readonly IPushNotificationService _pushNotificationService;
|
||||||
|
|
||||||
public CreateNotificationStatusCommand(ICurrentContext currentContext,
|
public CreateNotificationStatusCommand(ICurrentContext currentContext,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
INotificationRepository notificationRepository,
|
INotificationRepository notificationRepository,
|
||||||
INotificationStatusRepository notificationStatusRepository)
|
INotificationStatusRepository notificationStatusRepository,
|
||||||
|
IPushNotificationService pushNotificationService)
|
||||||
{
|
{
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_notificationRepository = notificationRepository;
|
_notificationRepository = notificationRepository;
|
||||||
_notificationStatusRepository = notificationStatusRepository;
|
_notificationStatusRepository = notificationStatusRepository;
|
||||||
|
_pushNotificationService = pushNotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<NotificationStatus> CreateAsync(NotificationStatus notificationStatus)
|
public async Task<NotificationStatus> CreateAsync(NotificationStatus notificationStatus)
|
||||||
@@ -42,6 +46,10 @@ public class CreateNotificationStatusCommand : ICreateNotificationStatusCommand
|
|||||||
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
||||||
NotificationStatusOperations.Create);
|
NotificationStatusOperations.Create);
|
||||||
|
|
||||||
return await _notificationStatusRepository.CreateAsync(notificationStatus);
|
var newNotificationStatus = await _notificationStatusRepository.CreateAsync(notificationStatus);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, newNotificationStatus);
|
||||||
|
|
||||||
|
return newNotificationStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@@ -16,16 +17,19 @@ public class MarkNotificationDeletedCommand : IMarkNotificationDeletedCommand
|
|||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly INotificationRepository _notificationRepository;
|
private readonly INotificationRepository _notificationRepository;
|
||||||
private readonly INotificationStatusRepository _notificationStatusRepository;
|
private readonly INotificationStatusRepository _notificationStatusRepository;
|
||||||
|
private readonly IPushNotificationService _pushNotificationService;
|
||||||
|
|
||||||
public MarkNotificationDeletedCommand(ICurrentContext currentContext,
|
public MarkNotificationDeletedCommand(ICurrentContext currentContext,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
INotificationRepository notificationRepository,
|
INotificationRepository notificationRepository,
|
||||||
INotificationStatusRepository notificationStatusRepository)
|
INotificationStatusRepository notificationStatusRepository,
|
||||||
|
IPushNotificationService pushNotificationService)
|
||||||
{
|
{
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_notificationRepository = notificationRepository;
|
_notificationRepository = notificationRepository;
|
||||||
_notificationStatusRepository = notificationStatusRepository;
|
_notificationStatusRepository = notificationStatusRepository;
|
||||||
|
_pushNotificationService = pushNotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MarkDeletedAsync(Guid notificationId)
|
public async Task MarkDeletedAsync(Guid notificationId)
|
||||||
@@ -59,7 +63,9 @@ public class MarkNotificationDeletedCommand : IMarkNotificationDeletedCommand
|
|||||||
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
||||||
NotificationStatusOperations.Create);
|
NotificationStatusOperations.Create);
|
||||||
|
|
||||||
await _notificationStatusRepository.CreateAsync(notificationStatus);
|
var newNotificationStatus = await _notificationStatusRepository.CreateAsync(notificationStatus);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, newNotificationStatus);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -69,6 +75,8 @@ public class MarkNotificationDeletedCommand : IMarkNotificationDeletedCommand
|
|||||||
notificationStatus.DeletedDate = DateTime.UtcNow;
|
notificationStatus.DeletedDate = DateTime.UtcNow;
|
||||||
|
|
||||||
await _notificationStatusRepository.UpdateAsync(notificationStatus);
|
await _notificationStatusRepository.UpdateAsync(notificationStatus);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, notificationStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@@ -16,16 +17,19 @@ public class MarkNotificationReadCommand : IMarkNotificationReadCommand
|
|||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly INotificationRepository _notificationRepository;
|
private readonly INotificationRepository _notificationRepository;
|
||||||
private readonly INotificationStatusRepository _notificationStatusRepository;
|
private readonly INotificationStatusRepository _notificationStatusRepository;
|
||||||
|
private readonly IPushNotificationService _pushNotificationService;
|
||||||
|
|
||||||
public MarkNotificationReadCommand(ICurrentContext currentContext,
|
public MarkNotificationReadCommand(ICurrentContext currentContext,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
INotificationRepository notificationRepository,
|
INotificationRepository notificationRepository,
|
||||||
INotificationStatusRepository notificationStatusRepository)
|
INotificationStatusRepository notificationStatusRepository,
|
||||||
|
IPushNotificationService pushNotificationService)
|
||||||
{
|
{
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_notificationRepository = notificationRepository;
|
_notificationRepository = notificationRepository;
|
||||||
_notificationStatusRepository = notificationStatusRepository;
|
_notificationStatusRepository = notificationStatusRepository;
|
||||||
|
_pushNotificationService = pushNotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MarkReadAsync(Guid notificationId)
|
public async Task MarkReadAsync(Guid notificationId)
|
||||||
@@ -59,7 +63,9 @@ public class MarkNotificationReadCommand : IMarkNotificationReadCommand
|
|||||||
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
await _authorizationService.AuthorizeOrThrowAsync(_currentContext.HttpContext.User, notificationStatus,
|
||||||
NotificationStatusOperations.Create);
|
NotificationStatusOperations.Create);
|
||||||
|
|
||||||
await _notificationStatusRepository.CreateAsync(notificationStatus);
|
var newNotificationStatus = await _notificationStatusRepository.CreateAsync(notificationStatus);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, newNotificationStatus);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -69,6 +75,8 @@ public class MarkNotificationReadCommand : IMarkNotificationReadCommand
|
|||||||
notificationStatus.ReadDate = DateTime.UtcNow;
|
notificationStatus.ReadDate = DateTime.UtcNow;
|
||||||
|
|
||||||
await _notificationStatusRepository.UpdateAsync(notificationStatus);
|
await _notificationStatusRepository.UpdateAsync(notificationStatus);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, notificationStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
using Bit.Core.NotificationCenter.Commands.Interfaces;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@@ -15,14 +16,17 @@ public class UpdateNotificationCommand : IUpdateNotificationCommand
|
|||||||
private readonly ICurrentContext _currentContext;
|
private readonly ICurrentContext _currentContext;
|
||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly INotificationRepository _notificationRepository;
|
private readonly INotificationRepository _notificationRepository;
|
||||||
|
private readonly IPushNotificationService _pushNotificationService;
|
||||||
|
|
||||||
public UpdateNotificationCommand(ICurrentContext currentContext,
|
public UpdateNotificationCommand(ICurrentContext currentContext,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
INotificationRepository notificationRepository)
|
INotificationRepository notificationRepository,
|
||||||
|
IPushNotificationService pushNotificationService)
|
||||||
{
|
{
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_notificationRepository = notificationRepository;
|
_notificationRepository = notificationRepository;
|
||||||
|
_pushNotificationService = pushNotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateAsync(Notification notificationToUpdate)
|
public async Task UpdateAsync(Notification notificationToUpdate)
|
||||||
@@ -43,5 +47,7 @@ public class UpdateNotificationCommand : IUpdateNotificationCommand
|
|||||||
notification.RevisionDate = DateTime.UtcNow;
|
notification.RevisionDate = DateTime.UtcNow;
|
||||||
|
|
||||||
await _notificationRepository.ReplaceAsync(notification);
|
await _notificationRepository.ReplaceAsync(notification);
|
||||||
|
|
||||||
|
await _pushNotificationService.PushSyncNotificationCreateAsync(notification, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Text.Json;
|
#nullable enable
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@@ -50,7 +52,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid>? collectionIds)
|
||||||
{
|
{
|
||||||
if (cipher.OrganizationId.HasValue)
|
if (cipher.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -180,7 +182,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
await PushAuthRequestAsync(authRequest, PushType.AuthRequestResponse);
|
await PushAuthRequestAsync(authRequest, PushType.AuthRequestResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PushSyncNotificationAsync(Notification notification)
|
public async Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
{
|
{
|
||||||
var message = new SyncNotificationPushNotification
|
var message = new SyncNotificationPushNotification
|
||||||
{
|
{
|
||||||
@@ -188,17 +190,44 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
UserId = notification.UserId,
|
UserId = notification.UserId,
|
||||||
OrganizationId = notification.OrganizationId,
|
OrganizationId = notification.OrganizationId,
|
||||||
ClientType = notification.ClientType,
|
ClientType = notification.ClientType,
|
||||||
RevisionDate = notification.RevisionDate
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
};
|
};
|
||||||
|
|
||||||
if (notification.UserId.HasValue)
|
if (notification.UserId.HasValue)
|
||||||
{
|
{
|
||||||
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotification, message, true,
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotificationCreate, message, true,
|
||||||
notification.ClientType);
|
notification.ClientType);
|
||||||
}
|
}
|
||||||
else if (notification.OrganizationId.HasValue)
|
else if (notification.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotification, message,
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotificationCreate, message,
|
||||||
|
true, notification.ClientType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
UserId = notification.UserId,
|
||||||
|
OrganizationId = notification.OrganizationId,
|
||||||
|
ClientType = notification.ClientType,
|
||||||
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
|
};
|
||||||
|
|
||||||
|
if (notification.UserId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotificationUpdate, message, true,
|
||||||
|
notification.ClientType);
|
||||||
|
}
|
||||||
|
else if (notification.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotificationUpdate, message,
|
||||||
true, notification.ClientType);
|
true, notification.ClientType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,8 +253,8 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
GetContextIdentifier(excludeCurrentContext), clientType: clientType);
|
GetContextIdentifier(excludeCurrentContext), clientType: clientType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string? identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
var tag = BuildTag($"template:payload_userId:{SanitizeTagInput(userId)}", identifier, clientType);
|
var tag = BuildTag($"template:payload_userId:{SanitizeTagInput(userId)}", identifier, clientType);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
await SendPayloadAsync(tag, type, payload);
|
||||||
@@ -235,8 +264,8 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string? identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
var tag = BuildTag($"template:payload && organizationId:{SanitizeTagInput(orgId)}", identifier, clientType);
|
var tag = BuildTag($"template:payload && organizationId:{SanitizeTagInput(orgId)}", identifier, clientType);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
await SendPayloadAsync(tag, type, payload);
|
||||||
@@ -246,7 +275,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
private string? GetContextIdentifier(bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
if (!excludeCurrentContext)
|
if (!excludeCurrentContext)
|
||||||
{
|
{
|
||||||
@@ -254,11 +283,11 @@ public class NotificationHubPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currentContext =
|
var currentContext =
|
||||||
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
return currentContext?.DeviceIdentifier;
|
return currentContext?.DeviceIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BuildTag(string tag, string identifier, ClientType? clientType)
|
private string BuildTag(string tag, string? identifier, ClientType? clientType)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(identifier))
|
if (!string.IsNullOrWhiteSpace(identifier))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@@ -23,13 +24,14 @@ public interface IPushNotificationService
|
|||||||
Task PushSyncSendCreateAsync(Send send);
|
Task PushSyncSendCreateAsync(Send send);
|
||||||
Task PushSyncSendUpdateAsync(Send send);
|
Task PushSyncSendUpdateAsync(Send send);
|
||||||
Task PushSyncSendDeleteAsync(Send send);
|
Task PushSyncSendDeleteAsync(Send send);
|
||||||
Task PushSyncNotificationAsync(Notification notification);
|
Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus);
|
||||||
|
Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus);
|
||||||
Task PushAuthRequestAsync(AuthRequest authRequest);
|
Task PushAuthRequestAsync(AuthRequest authRequest);
|
||||||
Task PushAuthRequestResponseAsync(AuthRequest authRequest);
|
Task PushAuthRequestResponseAsync(AuthRequest authRequest);
|
||||||
|
|
||||||
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null);
|
string? deviceId = null, ClientType? clientType = null);
|
||||||
|
|
||||||
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null);
|
string? deviceId = null, ClientType? clientType = null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text.Json;
|
#nullable enable
|
||||||
|
using System.Text.Json;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
@@ -41,7 +42,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid>? collectionIds)
|
||||||
{
|
{
|
||||||
if (cipher.OrganizationId.HasValue)
|
if (cipher.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -164,7 +165,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
await PushSendAsync(send, PushType.SyncSendDelete);
|
await PushSendAsync(send, PushType.SyncSendDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PushSyncNotificationAsync(Notification notification)
|
public async Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
{
|
{
|
||||||
var message = new SyncNotificationPushNotification
|
var message = new SyncNotificationPushNotification
|
||||||
{
|
{
|
||||||
@@ -172,10 +173,28 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
UserId = notification.UserId,
|
UserId = notification.UserId,
|
||||||
OrganizationId = notification.OrganizationId,
|
OrganizationId = notification.OrganizationId,
|
||||||
ClientType = notification.ClientType,
|
ClientType = notification.ClientType,
|
||||||
RevisionDate = notification.RevisionDate
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
};
|
};
|
||||||
|
|
||||||
await SendMessageAsync(PushType.SyncNotification, message, true);
|
await SendMessageAsync(PushType.SyncNotificationCreate, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
UserId = notification.UserId,
|
||||||
|
OrganizationId = notification.OrganizationId,
|
||||||
|
ClientType = notification.ClientType,
|
||||||
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
|
};
|
||||||
|
|
||||||
|
await SendMessageAsync(PushType.SyncNotificationUpdate, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushSendAsync(Send send, PushType type)
|
private async Task PushSendAsync(Send send, PushType type)
|
||||||
@@ -201,7 +220,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
await _queueClient.SendMessageAsync(message);
|
await _queueClient.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
private string? GetContextIdentifier(bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
if (!excludeCurrentContext)
|
if (!excludeCurrentContext)
|
||||||
{
|
{
|
||||||
@@ -214,14 +233,14 @@ public class AzureQueuePushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Settings;
|
using Bit.Core.Settings;
|
||||||
@@ -11,7 +12,7 @@ namespace Bit.Core.Services;
|
|||||||
|
|
||||||
public class MultiServicePushNotificationService : IPushNotificationService
|
public class MultiServicePushNotificationService : IPushNotificationService
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<IPushNotificationService> _services;
|
private readonly IEnumerable<IPushNotificationService>? _services;
|
||||||
private readonly ILogger<MultiServicePushNotificationService> _logger;
|
private readonly ILogger<MultiServicePushNotificationService> _logger;
|
||||||
|
|
||||||
public MultiServicePushNotificationService(
|
public MultiServicePushNotificationService(
|
||||||
@@ -23,7 +24,7 @@ public class MultiServicePushNotificationService : IPushNotificationService
|
|||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_logger.LogInformation("Hub services: {Services}", _services.Count());
|
_logger.LogInformation("Hub services: {Services}", _services.Count());
|
||||||
globalSettings?.NotificationHubPool?.NotificationHubs?.ForEach(hub =>
|
globalSettings.NotificationHubPool?.NotificationHubs?.ForEach(hub =>
|
||||||
{
|
{
|
||||||
_logger.LogInformation("HubName: {HubName}, EnableSendTracing: {EnableSendTracing}, RegistrationStartDate: {RegistrationStartDate}, RegistrationEndDate: {RegistrationEndDate}", hub.HubName, hub.EnableSendTracing, hub.RegistrationStartDate, hub.RegistrationEndDate);
|
_logger.LogInformation("HubName: {HubName}, EnableSendTracing: {EnableSendTracing}, RegistrationStartDate: {RegistrationStartDate}, RegistrationEndDate: {RegistrationEndDate}", hub.HubName, hub.EnableSendTracing, hub.RegistrationStartDate, hub.RegistrationEndDate);
|
||||||
});
|
});
|
||||||
@@ -132,33 +133,43 @@ public class MultiServicePushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier, deviceId, clientType));
|
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier, deviceId, clientType));
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier, deviceId, clientType));
|
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier, deviceId, clientType));
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task PushSyncNotificationAsync(Notification notification)
|
public Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
{
|
{
|
||||||
PushToServices((s) => s.PushSyncNotificationAsync(notification));
|
PushToServices((s) => s.PushSyncNotificationCreateAsync(notification, notificationStatus));
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
{
|
||||||
|
PushToServices((s) => s.PushSyncNotificationUpdateAsync(notification, notificationStatus));
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
|
private void PushToServices(Func<IPushNotificationService, Task> pushFunc)
|
||||||
{
|
{
|
||||||
if (_services != null)
|
if (_services == null)
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning("No services found to push notification");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var service in _services)
|
foreach (var service in _services)
|
||||||
{
|
{
|
||||||
|
_logger.LogDebug("Pushing notification to service {}", service.GetType().Name);
|
||||||
pushFunc(service);
|
pushFunc(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
@@ -13,7 +14,6 @@ namespace Bit.Core.Services;
|
|||||||
|
|
||||||
public class NotificationsApiPushNotificationService : BaseIdentityClientService, IPushNotificationService
|
public class NotificationsApiPushNotificationService : BaseIdentityClientService, IPushNotificationService
|
||||||
{
|
{
|
||||||
private readonly GlobalSettings _globalSettings;
|
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
public NotificationsApiPushNotificationService(
|
public NotificationsApiPushNotificationService(
|
||||||
@@ -30,7 +30,6 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
globalSettings.InternalIdentityKey,
|
globalSettings.InternalIdentityKey,
|
||||||
logger)
|
logger)
|
||||||
{
|
{
|
||||||
_globalSettings = globalSettings;
|
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +48,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid>? collectionIds)
|
||||||
{
|
{
|
||||||
if (cipher.OrganizationId.HasValue)
|
if (cipher.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -173,7 +172,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
await PushSendAsync(send, PushType.SyncSendDelete);
|
await PushSendAsync(send, PushType.SyncSendDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PushSyncNotificationAsync(Notification notification)
|
public async Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
{
|
{
|
||||||
var message = new SyncNotificationPushNotification
|
var message = new SyncNotificationPushNotification
|
||||||
{
|
{
|
||||||
@@ -181,10 +180,28 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
UserId = notification.UserId,
|
UserId = notification.UserId,
|
||||||
OrganizationId = notification.OrganizationId,
|
OrganizationId = notification.OrganizationId,
|
||||||
ClientType = notification.ClientType,
|
ClientType = notification.ClientType,
|
||||||
RevisionDate = notification.RevisionDate
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
};
|
};
|
||||||
|
|
||||||
await SendMessageAsync(PushType.SyncNotification, message, true);
|
await SendMessageAsync(PushType.SyncNotificationCreate, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
UserId = notification.UserId,
|
||||||
|
OrganizationId = notification.OrganizationId,
|
||||||
|
ClientType = notification.ClientType,
|
||||||
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
|
};
|
||||||
|
|
||||||
|
await SendMessageAsync(PushType.SyncNotificationUpdate, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushSendAsync(Send send, PushType type)
|
private async Task PushSendAsync(Send send, PushType type)
|
||||||
@@ -209,7 +226,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
await SendAsync(HttpMethod.Post, "send", request);
|
await SendAsync(HttpMethod.Post, "send", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
private string? GetContextIdentifier(bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
if (!excludeCurrentContext)
|
if (!excludeCurrentContext)
|
||||||
{
|
{
|
||||||
@@ -217,19 +234,19 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currentContext =
|
var currentContext =
|
||||||
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
return currentContext?.DeviceIdentifier;
|
return currentContext?.DeviceIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
// Noop
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.IdentityServer;
|
using Bit.Core.IdentityServer;
|
||||||
@@ -53,7 +54,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
|
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid>? collectionIds)
|
||||||
{
|
{
|
||||||
if (cipher.OrganizationId.HasValue)
|
if (cipher.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -189,7 +190,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
await SendPayloadToUserAsync(authRequest.UserId, type, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PushSyncNotificationAsync(Notification notification)
|
public async Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
{
|
{
|
||||||
var message = new SyncNotificationPushNotification
|
var message = new SyncNotificationPushNotification
|
||||||
{
|
{
|
||||||
@@ -197,17 +198,44 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
UserId = notification.UserId,
|
UserId = notification.UserId,
|
||||||
OrganizationId = notification.OrganizationId,
|
OrganizationId = notification.OrganizationId,
|
||||||
ClientType = notification.ClientType,
|
ClientType = notification.ClientType,
|
||||||
RevisionDate = notification.RevisionDate
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
};
|
};
|
||||||
|
|
||||||
if (notification.UserId.HasValue)
|
if (notification.UserId.HasValue)
|
||||||
{
|
{
|
||||||
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotification, message, true,
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotificationCreate, message, true,
|
||||||
notification.ClientType);
|
notification.ClientType);
|
||||||
}
|
}
|
||||||
else if (notification.OrganizationId.HasValue)
|
else if (notification.OrganizationId.HasValue)
|
||||||
{
|
{
|
||||||
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotification, message,
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotificationCreate, message,
|
||||||
|
true, notification.ClientType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
{
|
||||||
|
var message = new SyncNotificationPushNotification
|
||||||
|
{
|
||||||
|
Id = notification.Id,
|
||||||
|
UserId = notification.UserId,
|
||||||
|
OrganizationId = notification.OrganizationId,
|
||||||
|
ClientType = notification.ClientType,
|
||||||
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
|
};
|
||||||
|
|
||||||
|
if (notification.UserId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToUserAsync(notification.UserId.Value, PushType.SyncNotificationUpdate, message, true,
|
||||||
|
notification.ClientType);
|
||||||
|
}
|
||||||
|
else if (notification.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
await SendPayloadToOrganizationAsync(notification.OrganizationId.Value, PushType.SyncNotificationUpdate, message,
|
||||||
true, notification.ClientType);
|
true, notification.ClientType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,7 +273,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
||||||
{
|
{
|
||||||
var currentContext =
|
var currentContext =
|
||||||
_httpContextAccessor?.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
_httpContextAccessor.HttpContext?.RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
|
||||||
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
if (!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||||
{
|
{
|
||||||
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
||||||
@@ -262,13 +290,13 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Auth.Entities;
|
#nullable enable
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.Tools.Entities;
|
using Bit.Core.Tools.Entities;
|
||||||
@@ -84,7 +85,7 @@ public class NoopPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
@@ -100,10 +101,12 @@ public class NoopPushNotificationService : IPushNotificationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||||
string deviceId = null, ClientType? clientType = null)
|
string? deviceId = null, ClientType? clientType = null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task PushSyncNotificationAsync(Notification notification) => Task.CompletedTask;
|
public Task PushSyncNotificationCreateAsync(Notification notification, NotificationStatus? notificationStatus) => Task.CompletedTask;
|
||||||
|
|
||||||
|
public Task PushSyncNotificationUpdateAsync(Notification notification, NotificationStatus? notificationStatus) => Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ public static class HubHelpers
|
|||||||
await hubContext.Clients.User(authRequestNotification.Payload.UserId.ToString())
|
await hubContext.Clients.User(authRequestNotification.Payload.UserId.ToString())
|
||||||
.SendAsync(_receiveMessageMethod, authRequestNotification, cancellationToken);
|
.SendAsync(_receiveMessageMethod, authRequestNotification, cancellationToken);
|
||||||
break;
|
break;
|
||||||
case PushType.SyncNotification:
|
case PushType.SyncNotificationCreate:
|
||||||
|
case PushType.SyncNotificationUpdate:
|
||||||
var syncNotification =
|
var syncNotification =
|
||||||
JsonSerializer.Deserialize<PushNotificationData<SyncNotificationPushNotification>>(
|
JsonSerializer.Deserialize<PushNotificationData<SyncNotificationPushNotification>>(
|
||||||
notificationJson, _deserializerOptions);
|
notificationJson, _deserializerOptions);
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ public class CreateNotificationCommandTest
|
|||||||
Setup(sutProvider, notification, authorized: false);
|
Setup(sutProvider, notification, authorized: false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notification));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notification));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -58,6 +61,6 @@ public class CreateNotificationCommandTest
|
|||||||
Assert.Equal(notification.CreationDate, notification.RevisionDate);
|
Assert.Equal(notification.CreationDate, notification.RevisionDate);
|
||||||
await sutProvider.GetDependency<IPushNotificationService>()
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
.Received(1)
|
.Received(1)
|
||||||
.PushSyncNotificationAsync(newNotification);
|
.PushSyncNotificationCreateAsync(newNotification, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands;
|
using Bit.Core.NotificationCenter.Commands;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture.Attributes;
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
@@ -50,6 +51,9 @@ public class CreateNotificationStatusCommandTest
|
|||||||
Setup(sutProvider, notification: null, notificationStatus, true, true);
|
Setup(sutProvider, notification: null, notificationStatus, true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -61,6 +65,9 @@ public class CreateNotificationStatusCommandTest
|
|||||||
Setup(sutProvider, notification, notificationStatus, authorizedNotification: false, true);
|
Setup(sutProvider, notification, notificationStatus, authorizedNotification: false, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -72,6 +79,9 @@ public class CreateNotificationStatusCommandTest
|
|||||||
Setup(sutProvider, notification, notificationStatus, true, authorizedCreate: false);
|
Setup(sutProvider, notification, notificationStatus, true, authorizedCreate: false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -85,5 +95,8 @@ public class CreateNotificationStatusCommandTest
|
|||||||
var newNotificationStatus = await sutProvider.Sut.CreateAsync(notificationStatus);
|
var newNotificationStatus = await sutProvider.Sut.CreateAsync(notificationStatus);
|
||||||
|
|
||||||
Assert.Equal(notificationStatus, newNotificationStatus);
|
Assert.Equal(notificationStatus, newNotificationStatus);
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(1)
|
||||||
|
.PushSyncNotificationCreateAsync(notification, notificationStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands;
|
using Bit.Core.NotificationCenter.Commands;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture.Attributes;
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
@@ -63,6 +64,9 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -74,6 +78,9 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -86,6 +93,9 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
true, true);
|
true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -98,6 +108,9 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
authorizedCreate: false, true);
|
authorizedCreate: false, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -110,6 +123,9 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
authorizedUpdate: false);
|
authorizedUpdate: false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -119,13 +135,22 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
Guid notificationId, Guid userId, Notification notification)
|
Guid notificationId, Guid userId, Notification notification)
|
||||||
{
|
{
|
||||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true, true, true);
|
||||||
|
var expectedNotificationStatus = new NotificationStatus
|
||||||
|
{
|
||||||
|
NotificationId = notificationId,
|
||||||
|
UserId = userId,
|
||||||
|
ReadDate = null,
|
||||||
|
DeletedDate = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
||||||
|
|
||||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||||
.CreateAsync(Arg.Is<NotificationStatus>(ns =>
|
.CreateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||||
ns.NotificationId == notificationId && ns.UserId == userId && !ns.ReadDate.HasValue &&
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
ns.DeletedDate.HasValue && DateTime.UtcNow - ns.DeletedDate.Value < TimeSpan.FromMinutes(1)));
|
.Received(1)
|
||||||
|
.PushSyncNotificationCreateAsync(notification,
|
||||||
|
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -134,18 +159,27 @@ public class MarkNotificationDeletedCommandTest
|
|||||||
SutProvider<MarkNotificationDeletedCommand> sutProvider,
|
SutProvider<MarkNotificationDeletedCommand> sutProvider,
|
||||||
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
var deletedDate = notificationStatus.DeletedDate;
|
|
||||||
|
|
||||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
||||||
|
|
||||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||||
.UpdateAsync(Arg.Is<NotificationStatus>(ns =>
|
.UpdateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||||
ns.Equals(notificationStatus) &&
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
ns.NotificationId == notificationStatus.NotificationId && ns.UserId == notificationStatus.UserId &&
|
.Received(1)
|
||||||
ns.ReadDate == notificationStatus.ReadDate && ns.DeletedDate != deletedDate &&
|
.PushSyncNotificationCreateAsync(notification,
|
||||||
ns.DeletedDate.HasValue &&
|
Arg.Do<NotificationStatus?>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||||
DateTime.UtcNow - ns.DeletedDate.Value < TimeSpan.FromMinutes(1)));
|
}
|
||||||
|
|
||||||
|
private static void AssertNotificationStatus(NotificationStatus expectedNotificationStatus,
|
||||||
|
NotificationStatus? actualNotificationStatus)
|
||||||
|
{
|
||||||
|
Assert.NotNull(actualNotificationStatus);
|
||||||
|
Assert.Equal(expectedNotificationStatus.NotificationId, actualNotificationStatus.NotificationId);
|
||||||
|
Assert.Equal(expectedNotificationStatus.UserId, actualNotificationStatus.UserId);
|
||||||
|
Assert.Equal(expectedNotificationStatus.ReadDate, actualNotificationStatus.ReadDate);
|
||||||
|
Assert.NotEqual(expectedNotificationStatus.DeletedDate, actualNotificationStatus.DeletedDate);
|
||||||
|
Assert.NotNull(actualNotificationStatus.DeletedDate);
|
||||||
|
Assert.Equal(DateTime.UtcNow, actualNotificationStatus.DeletedDate.Value, TimeSpan.FromMinutes(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
|||||||
using Bit.Core.NotificationCenter.Commands;
|
using Bit.Core.NotificationCenter.Commands;
|
||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture.Attributes;
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
@@ -63,6 +64,9 @@ public class MarkNotificationReadCommandTest
|
|||||||
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -74,6 +78,9 @@ public class MarkNotificationReadCommandTest
|
|||||||
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -86,6 +93,9 @@ public class MarkNotificationReadCommandTest
|
|||||||
true, true);
|
true, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -98,6 +108,9 @@ public class MarkNotificationReadCommandTest
|
|||||||
authorizedCreate: false, true);
|
authorizedCreate: false, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -110,6 +123,9 @@ public class MarkNotificationReadCommandTest
|
|||||||
authorizedUpdate: false);
|
authorizedUpdate: false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -119,13 +135,22 @@ public class MarkNotificationReadCommandTest
|
|||||||
Guid notificationId, Guid userId, Notification notification)
|
Guid notificationId, Guid userId, Notification notification)
|
||||||
{
|
{
|
||||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true, true, true);
|
||||||
|
var expectedNotificationStatus = new NotificationStatus
|
||||||
|
{
|
||||||
|
NotificationId = notificationId,
|
||||||
|
UserId = userId,
|
||||||
|
ReadDate = DateTime.UtcNow,
|
||||||
|
DeletedDate = null
|
||||||
|
};
|
||||||
|
|
||||||
await sutProvider.Sut.MarkReadAsync(notificationId);
|
await sutProvider.Sut.MarkReadAsync(notificationId);
|
||||||
|
|
||||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||||
.CreateAsync(Arg.Is<NotificationStatus>(ns =>
|
.CreateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||||
ns.NotificationId == notificationId && ns.UserId == userId && !ns.DeletedDate.HasValue &&
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
ns.ReadDate.HasValue && DateTime.UtcNow - ns.ReadDate.Value < TimeSpan.FromMinutes(1)));
|
.Received(1)
|
||||||
|
.PushSyncNotificationCreateAsync(notification,
|
||||||
|
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -134,18 +159,27 @@ public class MarkNotificationReadCommandTest
|
|||||||
SutProvider<MarkNotificationReadCommand> sutProvider,
|
SutProvider<MarkNotificationReadCommand> sutProvider,
|
||||||
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
var readDate = notificationStatus.ReadDate;
|
|
||||||
|
|
||||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
||||||
|
|
||||||
await sutProvider.Sut.MarkReadAsync(notificationId);
|
await sutProvider.Sut.MarkReadAsync(notificationId);
|
||||||
|
|
||||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||||
.UpdateAsync(Arg.Is<NotificationStatus>(ns =>
|
.UpdateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||||
ns.Equals(notificationStatus) &&
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
ns.NotificationId == notificationStatus.NotificationId && ns.UserId == notificationStatus.UserId &&
|
.Received(1)
|
||||||
ns.DeletedDate == notificationStatus.DeletedDate && ns.ReadDate != readDate &&
|
.PushSyncNotificationCreateAsync(notification,
|
||||||
ns.ReadDate.HasValue &&
|
Arg.Do<NotificationStatus?>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||||
DateTime.UtcNow - ns.ReadDate.Value < TimeSpan.FromMinutes(1)));
|
}
|
||||||
|
|
||||||
|
private static void AssertNotificationStatus(NotificationStatus expectedNotificationStatus,
|
||||||
|
NotificationStatus? actualNotificationStatus)
|
||||||
|
{
|
||||||
|
Assert.NotNull(actualNotificationStatus);
|
||||||
|
Assert.Equal(expectedNotificationStatus.NotificationId, actualNotificationStatus.NotificationId);
|
||||||
|
Assert.Equal(expectedNotificationStatus.UserId, actualNotificationStatus.UserId);
|
||||||
|
Assert.NotEqual(expectedNotificationStatus.ReadDate, actualNotificationStatus.ReadDate);
|
||||||
|
Assert.NotNull(actualNotificationStatus.ReadDate);
|
||||||
|
Assert.Equal(DateTime.UtcNow, actualNotificationStatus.ReadDate.Value, TimeSpan.FromMinutes(1));
|
||||||
|
Assert.Equal(expectedNotificationStatus.DeletedDate, actualNotificationStatus.DeletedDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Bit.Core.NotificationCenter.Commands;
|
|||||||
using Bit.Core.NotificationCenter.Entities;
|
using Bit.Core.NotificationCenter.Entities;
|
||||||
using Bit.Core.NotificationCenter.Enums;
|
using Bit.Core.NotificationCenter.Enums;
|
||||||
using Bit.Core.NotificationCenter.Repositories;
|
using Bit.Core.NotificationCenter.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
@@ -45,6 +46,9 @@ public class UpdateNotificationCommandTest
|
|||||||
Setup(sutProvider, notification.Id, notification: null, true);
|
Setup(sutProvider, notification.Id, notification: null, true);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -56,6 +60,9 @@ public class UpdateNotificationCommandTest
|
|||||||
Setup(sutProvider, notification.Id, notification, authorized: false);
|
Setup(sutProvider, notification.Id, notification, authorized: false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(0)
|
||||||
|
.PushSyncNotificationCreateAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus?>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -91,5 +98,8 @@ public class UpdateNotificationCommandTest
|
|||||||
n.Priority == notificationToUpdate.Priority && n.ClientType == notificationToUpdate.ClientType &&
|
n.Priority == notificationToUpdate.Priority && n.ClientType == notificationToUpdate.ClientType &&
|
||||||
n.Title == notificationToUpdate.Title && n.Body == notificationToUpdate.Body &&
|
n.Title == notificationToUpdate.Title && n.Body == notificationToUpdate.Body &&
|
||||||
DateTime.UtcNow - n.RevisionDate < TimeSpan.FromMinutes(1)));
|
DateTime.UtcNow - n.RevisionDate < TimeSpan.FromMinutes(1)));
|
||||||
|
await sutProvider.GetDependency<IPushNotificationService>()
|
||||||
|
.Received(1)
|
||||||
|
.PushSyncNotificationCreateAsync(notification, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,19 @@ using Xunit;
|
|||||||
namespace Bit.Core.Test.NotificationHub;
|
namespace Bit.Core.Test.NotificationHub;
|
||||||
|
|
||||||
[SutProviderCustomize]
|
[SutProviderCustomize]
|
||||||
|
[NotificationStatusCustomize]
|
||||||
public class NotificationHubPushNotificationServiceTests
|
public class NotificationHubPushNotificationServiceTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
[NotificationCustomize]
|
[NotificationCustomize]
|
||||||
public async void PushSyncNotificationAsync_Global_NotSent(
|
public async Task PushSyncNotificationCreateAsync_Global_NotSent(bool notificationStatusNull,
|
||||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification)
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification,
|
||||||
|
notificationStatusNull ? null : notificationStatus);
|
||||||
|
|
||||||
await sutProvider.GetDependency<INotificationHubPool>()
|
await sutProvider.GetDependency<INotificationHubPool>()
|
||||||
.Received(0)
|
.Received(0)
|
||||||
@@ -36,12 +40,15 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData(false)]
|
[BitAutoData(false, false)]
|
||||||
[BitAutoData(true)]
|
[BitAutoData(false, true)]
|
||||||
|
[BitAutoData(true, false)]
|
||||||
|
[BitAutoData(true, true)]
|
||||||
[NotificationCustomize(false)]
|
[NotificationCustomize(false)]
|
||||||
public async void PushSyncNotificationAsync_UserIdProvidedClientTypeAll_SentToUser(
|
public async Task PushSyncNotificationCreateAsync_UserIdProvidedClientTypeAll_SentToUser(
|
||||||
bool organizationIdNull, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
bool organizationIdNull, bool notificationStatusNull,
|
||||||
Notification notification)
|
SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
if (organizationIdNull)
|
if (organizationIdNull)
|
||||||
{
|
{
|
||||||
@@ -49,11 +56,13 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
notification.ClientType = ClientType.All;
|
notification.ClientType = ClientType.All;
|
||||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationCreate,
|
||||||
|
expectedSyncNotification,
|
||||||
$"(template:payload_userId:{notification.UserId})");
|
$"(template:payload_userId:{notification.UserId})");
|
||||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
.Received(0)
|
.Received(0)
|
||||||
@@ -70,21 +79,20 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
[BitAutoData(true, ClientType.Web)]
|
[BitAutoData(true, ClientType.Web)]
|
||||||
[BitAutoData(true, ClientType.Mobile)]
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
[NotificationCustomize(false)]
|
[NotificationCustomize(false)]
|
||||||
public async void PushSyncNotificationAsync_UserIdProvidedClientTypeNotAll_SentToUser(bool organizationIdNull,
|
public async Task PushSyncNotificationCreateAsync_UserIdProvidedOrganizationIdNullClientTypeNotAll_SentToUser(
|
||||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
bool notificationStatusNull, ClientType clientType,
|
||||||
Notification notification)
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
{
|
NotificationStatus notificationStatus)
|
||||||
if (organizationIdNull)
|
|
||||||
{
|
{
|
||||||
notification.OrganizationId = null;
|
notification.OrganizationId = null;
|
||||||
}
|
|
||||||
|
|
||||||
notification.ClientType = clientType;
|
notification.ClientType = clientType;
|
||||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationCreate,
|
||||||
|
expectedSyncNotification,
|
||||||
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
.Received(0)
|
.Received(0)
|
||||||
@@ -92,18 +100,51 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData(false, ClientType.Browser)]
|
||||||
|
[BitAutoData(false, ClientType.Desktop)]
|
||||||
|
[BitAutoData(false, ClientType.Web)]
|
||||||
|
[BitAutoData(false, ClientType.Mobile)]
|
||||||
|
[BitAutoData(true, ClientType.Browser)]
|
||||||
|
[BitAutoData(true, ClientType.Desktop)]
|
||||||
|
[BitAutoData(true, ClientType.Web)]
|
||||||
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
[NotificationCustomize(false)]
|
[NotificationCustomize(false)]
|
||||||
public async void PushSyncNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
public async Task PushSyncNotificationCreateAsync_UserIdProvidedOrganizationIdProvidedClientTypeNotAll_SentToUser(
|
||||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification)
|
bool notificationStatusNull, ClientType clientType,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
notification.ClientType = clientType;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationCreate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task PushSyncNotificationCreateAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
||||||
|
bool notificationStatusNull, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
notification.UserId = null;
|
notification.UserId = null;
|
||||||
notification.ClientType = ClientType.All;
|
notification.ClientType = ClientType.All;
|
||||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationCreate,
|
||||||
|
expectedSyncNotification,
|
||||||
$"(template:payload && organizationId:{notification.OrganizationId})");
|
$"(template:payload && organizationId:{notification.OrganizationId})");
|
||||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
.Received(0)
|
.Received(0)
|
||||||
@@ -111,23 +152,194 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData(ClientType.Browser)]
|
[BitAutoData(false, ClientType.Browser)]
|
||||||
[BitAutoData(ClientType.Desktop)]
|
[BitAutoData(false, ClientType.Desktop)]
|
||||||
[BitAutoData(ClientType.Web)]
|
[BitAutoData(false, ClientType.Web)]
|
||||||
[BitAutoData(ClientType.Mobile)]
|
[BitAutoData(false, ClientType.Mobile)]
|
||||||
|
[BitAutoData(true, ClientType.Browser)]
|
||||||
|
[BitAutoData(true, ClientType.Desktop)]
|
||||||
|
[BitAutoData(true, ClientType.Web)]
|
||||||
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
[NotificationCustomize(false)]
|
[NotificationCustomize(false)]
|
||||||
public async void PushSyncNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
public async Task
|
||||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
PushSyncNotificationCreateAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
||||||
Notification notification)
|
bool notificationStatusNull, ClientType clientType,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
notification.UserId = null;
|
notification.UserId = null;
|
||||||
notification.ClientType = clientType;
|
notification.ClientType = clientType;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationCreate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload && organizationId:{notification.OrganizationId} && clientType:{clientType})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
[Theory]
|
||||||
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
|
[NotificationCustomize]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_Global_NotSent(bool notificationStatusNull,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification,
|
||||||
|
notificationStatusNull ? null : notificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<INotificationHubPool>()
|
||||||
|
.Received(0)
|
||||||
|
.AllClients
|
||||||
|
.Received(0)
|
||||||
|
.SendTemplateNotificationAsync(Arg.Any<IDictionary<string, string>>(), Arg.Any<string>());
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false, false)]
|
||||||
|
[BitAutoData(false, true)]
|
||||||
|
[BitAutoData(true, false)]
|
||||||
|
[BitAutoData(true, true)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_UserIdProvidedClientTypeAll_SentToUser(
|
||||||
|
bool organizationIdNull, bool notificationStatusNull,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
if (organizationIdNull)
|
||||||
|
{
|
||||||
|
notification.OrganizationId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.ClientType = ClientType.All;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationUpdate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload_userId:{notification.UserId})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false, ClientType.Browser)]
|
||||||
|
[BitAutoData(false, ClientType.Desktop)]
|
||||||
|
[BitAutoData(false, ClientType.Web)]
|
||||||
|
[BitAutoData(false, ClientType.Mobile)]
|
||||||
|
[BitAutoData(true, ClientType.Browser)]
|
||||||
|
[BitAutoData(true, ClientType.Desktop)]
|
||||||
|
[BitAutoData(true, ClientType.Web)]
|
||||||
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_UserIdProvidedOrganizationIdNullClientTypeNotAll_SentToUser(
|
||||||
|
bool notificationStatusNull, ClientType clientType,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
notification.OrganizationId = null;
|
||||||
|
notification.ClientType = clientType;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationUpdate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false, ClientType.Browser)]
|
||||||
|
[BitAutoData(false, ClientType.Desktop)]
|
||||||
|
[BitAutoData(false, ClientType.Web)]
|
||||||
|
[BitAutoData(false, ClientType.Mobile)]
|
||||||
|
[BitAutoData(true, ClientType.Browser)]
|
||||||
|
[BitAutoData(true, ClientType.Desktop)]
|
||||||
|
[BitAutoData(true, ClientType.Web)]
|
||||||
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_UserIdProvidedOrganizationIdProvidedClientTypeNotAll_SentToUser(
|
||||||
|
bool notificationStatusNull, ClientType clientType,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
notification.ClientType = clientType;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationUpdate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
||||||
|
bool notificationStatusNull, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||||
|
Notification notification, NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
notification.UserId = null;
|
||||||
|
notification.ClientType = ClientType.All;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationUpdate,
|
||||||
|
expectedSyncNotification,
|
||||||
|
$"(template:payload && organizationId:{notification.OrganizationId})");
|
||||||
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
|
.Received(0)
|
||||||
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false, ClientType.Browser)]
|
||||||
|
[BitAutoData(false, ClientType.Desktop)]
|
||||||
|
[BitAutoData(false, ClientType.Web)]
|
||||||
|
[BitAutoData(false, ClientType.Mobile)]
|
||||||
|
[BitAutoData(true, ClientType.Browser)]
|
||||||
|
[BitAutoData(true, ClientType.Desktop)]
|
||||||
|
[BitAutoData(true, ClientType.Web)]
|
||||||
|
[BitAutoData(true, ClientType.Mobile)]
|
||||||
|
[NotificationCustomize(false)]
|
||||||
|
public async Task
|
||||||
|
PushSyncNotificationUpdateAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
||||||
|
bool notificationStatusNull, ClientType clientType,
|
||||||
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
notification.UserId = null;
|
||||||
|
notification.ClientType = clientType;
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
var expectedSyncNotification = ToSyncNotificationPushNotification(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationUpdate,
|
||||||
|
expectedSyncNotification,
|
||||||
$"(template:payload && organizationId:{notification.OrganizationId} && clientType:{clientType})");
|
$"(template:payload && organizationId:{notification.OrganizationId} && clientType:{clientType})");
|
||||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||||
.Received(0)
|
.Received(0)
|
||||||
@@ -137,7 +349,7 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData([null])]
|
[BitAutoData([null])]
|
||||||
[BitAutoData(ClientType.All)]
|
[BitAutoData(ClientType.All)]
|
||||||
public async void SendPayloadToUserAsync_ClientTypeNullOrAll_SentToUser(ClientType? clientType,
|
public async Task SendPayloadToUserAsync_ClientTypeNullOrAll_SentToUser(ClientType? clientType,
|
||||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
||||||
string identifier)
|
string identifier)
|
||||||
{
|
{
|
||||||
@@ -156,7 +368,7 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
[BitAutoData(ClientType.Desktop)]
|
[BitAutoData(ClientType.Desktop)]
|
||||||
[BitAutoData(ClientType.Mobile)]
|
[BitAutoData(ClientType.Mobile)]
|
||||||
[BitAutoData(ClientType.Web)]
|
[BitAutoData(ClientType.Web)]
|
||||||
public async void SendPayloadToUserAsync_ClientTypeExplicit_SentToUserAndClientType(ClientType clientType,
|
public async Task SendPayloadToUserAsync_ClientTypeExplicit_SentToUserAndClientType(ClientType clientType,
|
||||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
||||||
string identifier)
|
string identifier)
|
||||||
{
|
{
|
||||||
@@ -173,7 +385,7 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData([null])]
|
[BitAutoData([null])]
|
||||||
[BitAutoData(ClientType.All)]
|
[BitAutoData(ClientType.All)]
|
||||||
public async void SendPayloadToOrganizationAsync_ClientTypeNullOrAll_SentToOrganization(ClientType? clientType,
|
public async Task SendPayloadToOrganizationAsync_ClientTypeNullOrAll_SentToOrganization(ClientType? clientType,
|
||||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId, PushType pushType,
|
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId, PushType pushType,
|
||||||
string payload, string identifier)
|
string payload, string identifier)
|
||||||
{
|
{
|
||||||
@@ -192,7 +404,7 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
[BitAutoData(ClientType.Desktop)]
|
[BitAutoData(ClientType.Desktop)]
|
||||||
[BitAutoData(ClientType.Mobile)]
|
[BitAutoData(ClientType.Mobile)]
|
||||||
[BitAutoData(ClientType.Web)]
|
[BitAutoData(ClientType.Web)]
|
||||||
public async void SendPayloadToOrganizationAsync_ClientTypeExplicit_SentToOrganizationAndClientType(
|
public async Task SendPayloadToOrganizationAsync_ClientTypeExplicit_SentToOrganizationAndClientType(
|
||||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId,
|
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId,
|
||||||
PushType pushType, string payload, string identifier)
|
PushType pushType, string payload, string identifier)
|
||||||
{
|
{
|
||||||
@@ -206,14 +418,17 @@ public class NotificationHubPushNotificationServiceTests
|
|||||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SyncNotificationPushNotification ToSyncNotificationPushNotification(Notification notification) =>
|
private static SyncNotificationPushNotification ToSyncNotificationPushNotification(Notification notification,
|
||||||
|
NotificationStatus? notificationStatus) =>
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
Id = notification.Id,
|
Id = notification.Id,
|
||||||
UserId = notification.UserId,
|
UserId = notification.UserId,
|
||||||
OrganizationId = notification.OrganizationId,
|
OrganizationId = notification.OrganizationId,
|
||||||
ClientType = notification.ClientType,
|
ClientType = notification.ClientType,
|
||||||
RevisionDate = notification.RevisionDate
|
RevisionDate = notification.RevisionDate,
|
||||||
|
ReadDate = notificationStatus?.ReadDate,
|
||||||
|
DeletedDate = notificationStatus?.DeletedDate
|
||||||
};
|
};
|
||||||
|
|
||||||
private static async Task AssertSendTemplateNotificationAsync(
|
private static async Task AssertSendTemplateNotificationAsync(
|
||||||
|
|||||||
@@ -22,22 +22,50 @@ namespace Bit.Core.Test.Services;
|
|||||||
public class AzureQueuePushNotificationServiceTests
|
public class AzureQueuePushNotificationServiceTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
[NotificationCustomize]
|
[NotificationCustomize]
|
||||||
|
[NotificationStatusCustomize]
|
||||||
[CurrentContextCustomize]
|
[CurrentContextCustomize]
|
||||||
public async void PushSyncNotificationAsync_Notification_Sent(
|
public async Task PushSyncNotificationCreateAsync_Notification_Sent(bool notificationStatusNull,
|
||||||
SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
|
SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
|
||||||
ICurrentContext currentContext)
|
ICurrentContext currentContext, NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
currentContext.DeviceIdentifier.Returns(deviceIdentifier.ToString());
|
currentContext.DeviceIdentifier.Returns(deviceIdentifier.ToString());
|
||||||
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext!.RequestServices
|
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext!.RequestServices
|
||||||
.GetService(Arg.Any<Type>()).Returns(currentContext);
|
.GetService(Arg.Any<Type>()).Returns(currentContext);
|
||||||
|
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
await sutProvider.GetDependency<QueueClient>().Received(1)
|
await sutProvider.GetDependency<QueueClient>().Received(1)
|
||||||
.SendMessageAsync(Arg.Is<string>(message =>
|
.SendMessageAsync(Arg.Is<string>(message =>
|
||||||
MatchMessage(PushType.SyncNotification, message, new SyncNotificationEquals(notification),
|
MatchMessage(PushType.SyncNotificationCreate, message,
|
||||||
|
new SyncNotificationEquals(notification, expectedNotificationStatus),
|
||||||
|
deviceIdentifier.ToString())));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
|
[NotificationCustomize]
|
||||||
|
[NotificationStatusCustomize]
|
||||||
|
[CurrentContextCustomize]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_Notification_Sent(bool notificationStatusNull,
|
||||||
|
SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
|
||||||
|
ICurrentContext currentContext, NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
currentContext.DeviceIdentifier.Returns(deviceIdentifier.ToString());
|
||||||
|
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext!.RequestServices
|
||||||
|
.GetService(Arg.Any<Type>()).Returns(currentContext);
|
||||||
|
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<QueueClient>().Received(1)
|
||||||
|
.SendMessageAsync(Arg.Is<string>(message =>
|
||||||
|
MatchMessage(PushType.SyncNotificationUpdate, message,
|
||||||
|
new SyncNotificationEquals(notification, expectedNotificationStatus),
|
||||||
deviceIdentifier.ToString())));
|
deviceIdentifier.ToString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +80,8 @@ public class AzureQueuePushNotificationServiceTests
|
|||||||
pushNotificationData.ContextId == contextId;
|
pushNotificationData.ContextId == contextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SyncNotificationEquals(Notification notification) : IEquatable<SyncNotificationPushNotification>
|
private class SyncNotificationEquals(Notification notification, NotificationStatus? notificationStatus)
|
||||||
|
: IEquatable<SyncNotificationPushNotification>
|
||||||
{
|
{
|
||||||
public bool Equals(SyncNotificationPushNotification? other)
|
public bool Equals(SyncNotificationPushNotification? other)
|
||||||
{
|
{
|
||||||
@@ -61,7 +90,9 @@ public class AzureQueuePushNotificationServiceTests
|
|||||||
other.UserId == notification.UserId &&
|
other.UserId == notification.UserId &&
|
||||||
other.OrganizationId == notification.OrganizationId &&
|
other.OrganizationId == notification.OrganizationId &&
|
||||||
other.ClientType == notification.ClientType &&
|
other.ClientType == notification.ClientType &&
|
||||||
other.RevisionDate == notification.RevisionDate;
|
other.RevisionDate == notification.RevisionDate &&
|
||||||
|
other.ReadDate == notificationStatus?.ReadDate &&
|
||||||
|
other.DeletedDate == notificationStatus?.DeletedDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,17 +14,41 @@ namespace Bit.Core.Test.Services;
|
|||||||
public class MultiServicePushNotificationServiceTests
|
public class MultiServicePushNotificationServiceTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
[NotificationCustomize]
|
[NotificationCustomize]
|
||||||
public async Task PushSyncNotificationAsync_Notification_Sent(
|
[NotificationStatusCustomize]
|
||||||
SutProvider<MultiServicePushNotificationService> sutProvider, Notification notification)
|
public async Task PushSyncNotificationCreateAsync_Notification_Sent(bool notificationStatusNull,
|
||||||
|
SutProvider<MultiServicePushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
{
|
{
|
||||||
await sutProvider.Sut.PushSyncNotificationAsync(notification);
|
await sutProvider.Sut.PushSyncNotificationCreateAsync(notification,
|
||||||
|
notificationStatusNull ? null : notificationStatus);
|
||||||
|
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
await sutProvider.GetDependency<IEnumerable<IPushNotificationService>>()
|
await sutProvider.GetDependency<IEnumerable<IPushNotificationService>>()
|
||||||
.First()
|
.First()
|
||||||
.Received(1)
|
.Received(1)
|
||||||
.PushSyncNotificationAsync(notification);
|
.PushSyncNotificationCreateAsync(notification, expectedNotificationStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData(false)]
|
||||||
|
[BitAutoData(true)]
|
||||||
|
[NotificationCustomize]
|
||||||
|
[NotificationStatusCustomize]
|
||||||
|
public async Task PushSyncNotificationUpdateAsync_Notification_Sent(bool notificationStatusNull,
|
||||||
|
SutProvider<MultiServicePushNotificationService> sutProvider, Notification notification,
|
||||||
|
NotificationStatus notificationStatus)
|
||||||
|
{
|
||||||
|
await sutProvider.Sut.PushSyncNotificationUpdateAsync(notification,
|
||||||
|
notificationStatusNull ? null : notificationStatus);
|
||||||
|
|
||||||
|
var expectedNotificationStatus = notificationStatusNull ? null : notificationStatus;
|
||||||
|
await sutProvider.GetDependency<IEnumerable<IPushNotificationService>>()
|
||||||
|
.First()
|
||||||
|
.Received(1)
|
||||||
|
.PushSyncNotificationUpdateAsync(notification, expectedNotificationStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|||||||
Reference in New Issue
Block a user