Adding
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
**/*.bat
|
||||
**/*.log
|
||||
**/*.md
|
||||
**/*.yml
|
||||
**/.dockerignore
|
||||
**/.editorconfig
|
||||
**/.git
|
||||
**/.gitattributes
|
||||
**/.gitignore
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/bin
|
||||
**/dist
|
||||
**/dockerfile
|
||||
**/node_modules
|
||||
**/obj
|
||||
**/package-lock.json
|
||||
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
@@ -0,0 +1,330 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
@@ -0,0 +1,37 @@
|
||||
# .NET Core SDK
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS aspnetcore-build
|
||||
|
||||
# Copy Projects
|
||||
COPY LCU.API.Internal.MemberPreferencesApi/LCU.API.Internal.MemberPreferencesApi.csproj ./source/LCU.API.Internal.MemberPreferencesApi/
|
||||
COPY LCU.API.Internal.MemberPreferencesApiLib/LCU.API.Internal.MemberPreferencesApiLib.csproj ./source/LCU.API.Internal.MemberPreferencesApiLib/
|
||||
COPY LCU.Library.Internal.MemberPreferencesApiModels/LCU.Library.Internal.MemberPreferencesApiModels.csproj ./source/LCU.Library.Internal.MemberPreferencesApiModels/
|
||||
|
||||
# Install Credential Provider and set env variables to enable Nuget restore with auth
|
||||
ARG PAT=bh2lq3jibktw67b2wdbqyfln7cd3je6lk52kijntpj43v6kimpgq
|
||||
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | sh
|
||||
|
||||
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
|
||||
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json\", \"password\":\"${PAT}\"}]}"
|
||||
|
||||
RUN dotnet restore -s "https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json" -s "https://api.nuget.org/v3/index.json" ./source/LCU.API.Internal.MemberPreferencesApi/LCU.API.Internal.MemberPreferencesApi.csproj
|
||||
|
||||
# Copy All Files
|
||||
COPY . ./source/
|
||||
|
||||
LABEL test=true
|
||||
COPY LCU.API.Internal.MemberPreferencesApi.UnitTests/LCU.API.Internal.MemberPreferencesApi.UnitTests.csproj ./source/LCU.API.Internal.MemberPreferencesApi.UnitTests/
|
||||
RUN dotnet restore ./source/LCU.API.Internal.MemberPreferencesApi.UnitTests/LCU.API.Internal.MemberPreferencesApi.UnitTests.csproj
|
||||
RUN dotnet test -c Release --results-directory /testresults --logger "trx;LogFileName=test_results.trx" ./source/LCU.API.Internal.MemberPreferencesApi.UnitTests/LCU.API.Internal.MemberPreferencesApi.UnitTests.csproj
|
||||
|
||||
# .NET Core Publish
|
||||
RUN dotnet publish ./source/LCU.API.Internal.MemberPreferencesApi/LCU.API.Internal.MemberPreferencesApi.csproj -c Release -o /dist
|
||||
|
||||
# ASP.NET Core
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine3.20
|
||||
RUN apk add --no-cache icu-libs && apk add --no-cache tzdata;
|
||||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
|
||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=aspnetcore-build /dist .
|
||||
ENTRYPOINT ["dotnet", "LCU.API.Internal.MemberPreferencesApi.dll"]
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="MemberPreference\**" />
|
||||
<EmbeddedResource Remove="MemberPreference\**" />
|
||||
<None Remove="MemberPreference\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Api.Internal.FTPLib" Version="2.11.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="nunit" Version="4.1.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
<PackageReference Include="Respawn" Version="3.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.API.Internal.MemberPreferencesApi\LCU.API.Internal.MemberPreferencesApi.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.IntegrationTests
|
||||
{
|
||||
public class XdiTransferTest
|
||||
{
|
||||
private IXdiBatchService _xdiBatchItemService;
|
||||
private Mock<IXdiBatchItemsRepository> _mockBatchItemsRepository;
|
||||
private Mock<IUnitOfWork> _mockUnitOfWork;
|
||||
private XdiSftpApiConfiguration _xdiSftpConfiguration;
|
||||
private FtpApiConfiguration _ftpConfiguration;
|
||||
private Mock<IUnifiedOptInRepository> _mockUnifiedOptinRepository;
|
||||
private Mock<IMemberPreferenceRepository> _mockMemberPreferenceRepository;
|
||||
private Mock<IFtpApiService> _mockFtpApiService;
|
||||
private ConnectionConfiguration _connectionConfiguration;
|
||||
private ReceiveEndpointConfiguration _completionReceiveEndpoint;
|
||||
private ReceiveEndpointConfigurations _endpointConfiguration;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mockFtpApiService = new Mock<IFtpApiService>();
|
||||
_connectionConfiguration = new ConnectionConfiguration();
|
||||
_mockBatchItemsRepository = new Mock<IXdiBatchItemsRepository>();
|
||||
_mockMemberPreferenceRepository = new Mock<IMemberPreferenceRepository>();
|
||||
_endpointConfiguration = new ReceiveEndpointConfigurations();
|
||||
_completionReceiveEndpoint = _endpointConfiguration.XdiBatchConfirmEndpoint;
|
||||
_mockUnitOfWork = new Mock<IUnitOfWork>();
|
||||
_ftpConfiguration = new FtpApiConfiguration()
|
||||
{
|
||||
Url = "https://qa-ftpapi.lcu-internal.com/api/"
|
||||
};
|
||||
_xdiSftpConfiguration = new XdiSftpApiConfiguration()
|
||||
|
||||
{
|
||||
HostName = "sftp.xdi.com",
|
||||
UserName = "LANDMARKCU",
|
||||
PortNumber = 22,
|
||||
Password = "FILLMEIN",
|
||||
Fingerprint = "ssh-dss 2048 12:78:33:0a:cf:71:21:e2:8b:0e:ef:6a:8a:c6:8e:4f"
|
||||
};
|
||||
|
||||
_mockUnifiedOptinRepository = new Mock<IUnifiedOptInRepository>();
|
||||
_xdiBatchItemService = new XdiBatchService(_mockBatchItemsRepository.Object, _mockUnitOfWork.Object,
|
||||
_xdiSftpConfiguration, _mockUnifiedOptinRepository.Object, _mockMemberPreferenceRepository.Object,
|
||||
_connectionConfiguration, _endpointConfiguration, _mockFtpApiService.Object);
|
||||
}
|
||||
|
||||
|
||||
[Ignore("This will actually create the items and FTP them to XDI Test Folder. Be Careful. Fill in password.")]
|
||||
public void Test_Send_Test_Files()
|
||||
{
|
||||
IReadOnlyCollection<XdiBatchItem> items = new List<XdiBatchItem>()
|
||||
{
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "100"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "101"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "102"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "103"
|
||||
}
|
||||
};
|
||||
|
||||
var settings = new List<MemberOptInSettings>()
|
||||
{
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
LastUpdated = DateTime.Now,
|
||||
LegalDate = DateTime.Now,
|
||||
LegalVersion = "1.2.3",
|
||||
UserId = "99",
|
||||
CreatedByType = UserType.Associate,
|
||||
LastUpdatedByType = UserType.System,
|
||||
CreatedBy = "test",
|
||||
Created = DateTime.Now,
|
||||
LastUpdatedBy = "test"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1001,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "100"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1002,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Paper,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "101"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1003,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = null,
|
||||
UserId = "102"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1004,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "103"
|
||||
}
|
||||
};
|
||||
|
||||
_mockBatchItemsRepository.Setup(x => x.GetXdiBatchItems()).ReturnsAsync(items);
|
||||
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
_mockUnifiedOptinRepository.Setup(x => x.GetMemberOptInSettings(setting.UserId))
|
||||
.ReturnsAsync(setting);
|
||||
}
|
||||
|
||||
_mockBatchItemsRepository.Setup(x => x.SaveAsync(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
_mockBatchItemsRepository.Setup(x => x.Delete(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.FeatureManagement;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Controllers
|
||||
{
|
||||
public class MemberEmailControllerTest
|
||||
{
|
||||
private readonly MemberEmailController _controller;
|
||||
|
||||
private readonly Mock<IMemberEmailService> _service = new Mock<IMemberEmailService>();
|
||||
private readonly Mock<IFeatureManager> _featureManager = new Mock<IFeatureManager>();
|
||||
|
||||
public MemberEmailControllerTest()
|
||||
{
|
||||
_controller = new MemberEmailController(_service.Object, _featureManager.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSentSuccessfully_AllCases_CallsServiceUnifiedOptInEmailFailedToSend()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
|
||||
await _controller.EmailSentSuccessfully(userId, emailAddress);
|
||||
|
||||
_service.Verify(s => s.EmailSucceededToSend(userId, emailAddress), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSentSuccessfully_KnownEmail_ReturnsOk()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
_service
|
||||
.Setup(s => s.EmailSucceededToSend(userId, emailAddress))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var result = await _controller.EmailSentSuccessfully(userId, emailAddress);
|
||||
|
||||
Assert.AreEqual(200, (result as IStatusCodeActionResult)?.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSentSuccessfully_UnknownEmail_ReturnsNotFound()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
_service
|
||||
.Setup(s => s.EmailFailedToSend(userId, emailAddress, true))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
var result = await _controller.EmailSentSuccessfully(userId, emailAddress);
|
||||
|
||||
Assert.AreEqual(404, (result as IStatusCodeActionResult)?.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSendFailed_AllCases_CallsServiceEmailFailedToSend()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
_featureManager.Setup(f => f.IsEnabledAsync(It.IsAny<string>())).ReturnsAsync(true);
|
||||
|
||||
await _controller.EmailSendFailed(userId, emailAddress);
|
||||
|
||||
_service.Verify(s => s.EmailFailedToSend(userId, emailAddress, true), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSendFailed_KnownEmail_ReturnsOk()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
_featureManager.Setup(f => f.IsEnabledAsync(It.IsAny<string>())).ReturnsAsync(true);
|
||||
_service
|
||||
.Setup(s => s.EmailFailedToSend(userId, emailAddress, true))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var result = await _controller.EmailSendFailed(userId, emailAddress);
|
||||
|
||||
Assert.AreEqual(200, (result as IStatusCodeActionResult)?.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSendFailed_UnknownEmail_ReturnsNotFound()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var emailAddress = Guid.NewGuid().ToString();
|
||||
_service
|
||||
.Setup(s => s.EmailFailedToSend(userId, emailAddress, true))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
var result = await _controller.EmailSendFailed(userId, emailAddress);
|
||||
|
||||
Assert.AreEqual(404, (result as IStatusCodeActionResult)?.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.DataTransfer;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Requests;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Controllers
|
||||
{
|
||||
public class MemberOptInSettingsControllerTest
|
||||
{
|
||||
private MemberOptInSettingsController _controller;
|
||||
private Mock<IOptinService> _mockOptinService;
|
||||
private Mock<IMemberPreferenceService> _mockMemberPreferenceService;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mockOptinService = new Mock<IOptinService>();
|
||||
_mockMemberPreferenceService = new Mock<IMemberPreferenceService>();
|
||||
_controller =
|
||||
new MemberOptInSettingsController(_mockOptinService.Object, _mockMemberPreferenceService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Search_OK()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationByAccountId(123)).ReturnsAsync(
|
||||
new List<MemberOptInAgreementInformation>()
|
||||
{
|
||||
new MemberOptInAgreementInformation(new MemberOptInSettings()
|
||||
{
|
||||
Id = 1
|
||||
},
|
||||
null,
|
||||
null,
|
||||
false)
|
||||
}).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementsByAccountId(123);
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as List<MemberOptInAgreementInformation>;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.IsNotEmpty(okValue);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Search_Missing()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationByAccountId(123)).ReturnsAsync(
|
||||
new List<MemberOptInAgreementInformation>()).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementsByAccountId(123);
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as NotFoundObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(404, okResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Search_BadRequest()
|
||||
{
|
||||
var result = await _controller.GetAgreementsByAccountId(0);
|
||||
Assert.NotNull(result);
|
||||
|
||||
var brResult = result as BadRequestObjectResult;
|
||||
Assert.NotNull(brResult);
|
||||
Assert.AreEqual(400, brResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify(x => x.GetMemberOptInAgreementInformationByAccountId(It.IsAny<long>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Search_Failure()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationByAccountId(123))
|
||||
.Throws(new Exception("Exception thrown from unit test.")).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementsByAccountId(123);
|
||||
Assert.NotNull(result);
|
||||
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMemberOptinAgreementInformationByUserId_OK()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationForUser("123")).ReturnsAsync(
|
||||
new MemberOptInAgreementInformation(new MemberOptInSettings()
|
||||
{
|
||||
Id = 1
|
||||
},
|
||||
null,
|
||||
null,
|
||||
false)
|
||||
).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementByUserId("123");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as MemberOptInAgreementInformation;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.AreEqual(1 ,okValue.MemberOptinSettings.Id);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMemberOptinAgreementInformationByUserId_Missing()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationForUser("123")).ReturnsAsync(
|
||||
(MemberOptInAgreementInformation)null).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementByUserId("123");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as NotFoundObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(404, okResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMemberOptinAgreementInformationByUserId_BadRequest()
|
||||
{
|
||||
var result = await _controller.GetAgreementByUserId(null);
|
||||
Assert.NotNull(result);
|
||||
|
||||
var brResult = result as BadRequestObjectResult;
|
||||
Assert.NotNull(brResult);
|
||||
Assert.AreEqual(400, brResult.StatusCode);
|
||||
|
||||
result = await _controller.GetAgreementByUserId("");
|
||||
Assert.NotNull(result);
|
||||
|
||||
brResult = result as BadRequestObjectResult;
|
||||
Assert.NotNull(brResult);
|
||||
Assert.AreEqual(400, brResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify(x => x.GetMemberOptInAgreementInformationForUser(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMemberOptinAgreementInformationByUserId_Failure()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInAgreementInformationForUser("123"))
|
||||
.Throws(new Exception("Exception thrown from unit test.")).Verifiable();
|
||||
|
||||
var result = await _controller.GetAgreementByUserId("123");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMember_OK()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInSettingsOrCreateDefaultSetting(It.IsAny<string>())).ReturnsAsync(
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1
|
||||
}).Verifiable();
|
||||
|
||||
_mockOptinService
|
||||
.Setup(x => x.TransformMemberOptInSettingsForClient(It.IsAny<MemberOptInSettings>())).ReturnsAsync(
|
||||
new MemberOptInInformation(new MemberOptInSettings {Id = 1},true)).Verifiable();
|
||||
|
||||
var result = await _controller.GetMemberById("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as MemberOptInInformation;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.AreEqual(1, okValue.MemberOptinSettings.Id);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMember_Missing()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInSettingsOrCreateDefaultSetting("99")).ReturnsAsync(
|
||||
(MemberOptInSettings) null).Verifiable();
|
||||
|
||||
var result = await _controller.GetMemberById("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as NotFoundObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(404, okResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMember_Failure()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInSettingsOrCreateDefaultSetting("99"))
|
||||
.Throws(new InvalidCastException()).Verifiable();
|
||||
|
||||
var result = await _controller.GetMemberById("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
_mockOptinService.Verify(x => x.TransformMemberOptInSettingsForClient(It.IsAny<MemberOptInSettings>()), Times.Never);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task GetMember_Transform_Failure()
|
||||
{
|
||||
_mockOptinService
|
||||
.Setup(service => service.GetMemberOptInSettingsOrCreateDefaultSetting("99")).ReturnsAsync(
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1
|
||||
}).Verifiable();
|
||||
|
||||
_mockOptinService
|
||||
.Setup(x => x.TransformMemberOptInSettingsForClient(It.IsAny<MemberOptInSettings>()))
|
||||
.ThrowsAsync(new Exception("Oops")).Verifiable();
|
||||
|
||||
var result = await _controller.GetMemberById("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
|
||||
_mockOptinService.Verify();
|
||||
_mockOptinService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Email_OK()
|
||||
{
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = "Email",
|
||||
UserId = "99",
|
||||
Email = "[email protected]",
|
||||
LegalReference = "None"
|
||||
};
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.UpdateMemberOptinAsync(It.IsAny<MemberOptinRequest>()))
|
||||
.Verifiable("Expected call to UpdateMemberOptinAsync");
|
||||
|
||||
var result = await _controller.UpdateOptinPreference(request, "test", "Associate");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
_mockMemberPreferenceService.Verify(x => x.UpdateMemberOptinAsync(It.IsAny<MemberOptinRequest>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Bad_Request()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = null,
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
_controller.ModelState.AddModelError("Value", "The value field is required.");
|
||||
|
||||
// act
|
||||
var result = await _controller.UpdateOptinPreference(request, "test", "Associate");
|
||||
Assert.NotNull(result);
|
||||
var badRequestResult = result as BadRequestObjectResult;
|
||||
|
||||
// assert
|
||||
Assert.NotNull(badRequestResult);
|
||||
Assert.AreEqual(StatusCodes.Status400BadRequest, badRequestResult.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Error()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = "True",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.UpdateMemberOptinAsync(It.IsAny<MemberOptinRequest>()))
|
||||
.ThrowsAsync(new ArithmeticException());
|
||||
|
||||
// act
|
||||
var result = await _controller.UpdateOptinPreference(request, "test", "Associate");
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
|
||||
_mockMemberPreferenceService.Verify(x => x.UpdateMemberOptinAsync(It.IsAny<MemberOptinRequest>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Bad_Request_NoHeader()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = "Paper",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
// act
|
||||
var result = await _controller.UpdateOptinPreference(request, null, null);
|
||||
Assert.NotNull(result);
|
||||
var badRequestResult = result as BadRequestObjectResult;
|
||||
|
||||
// assert
|
||||
Assert.NotNull(badRequestResult);
|
||||
Assert.AreEqual(StatusCodes.Status400BadRequest, badRequestResult.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Bad_Request_NotValid()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = "Electronic",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.UpdateMemberOptinAsync(It.IsAny<MemberOptinRequest>()))
|
||||
.ThrowsAsync(new Exception());
|
||||
|
||||
// act
|
||||
var result = await _controller.UpdateOptinPreference(request, null, null);
|
||||
Assert.NotNull(result);
|
||||
var badRequestResult = result as BadRequestObjectResult;
|
||||
|
||||
// assert
|
||||
Assert.NotNull(badRequestResult);
|
||||
Assert.AreEqual(StatusCodes.Status400BadRequest, badRequestResult.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Requests;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Controllers
|
||||
{
|
||||
public class MemberPreferenceControllerTest
|
||||
{
|
||||
private MemberPreferenceController _controller;
|
||||
private Mock<IMemberPreferenceService> _mockMemberPreferenceService;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mockMemberPreferenceService = new Mock<IMemberPreferenceService>();
|
||||
_controller = new MemberPreferenceController(_mockMemberPreferenceService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Get_OK()
|
||||
{
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.GetMemberPreferencesAsync("99")).ReturnsAsync(
|
||||
new List<MemberPreference>()
|
||||
{
|
||||
new MemberPreference()
|
||||
{
|
||||
Id = 1,
|
||||
UserId = "99",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "true"
|
||||
}
|
||||
}).Verifiable();
|
||||
|
||||
var result = await _controller.Get("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as IReadOnlyCollection<MemberPreference>;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.IsNotEmpty(okValue);
|
||||
Assert.AreEqual(1, okValue.First().Id);
|
||||
_mockMemberPreferenceService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Get_Missing()
|
||||
{
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.GetMemberPreferencesAsync("99")).ReturnsAsync(
|
||||
new List<MemberPreference>()).Verifiable();
|
||||
|
||||
var result = await _controller.Get("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as IReadOnlyCollection<MemberPreference>;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.IsEmpty(okValue);
|
||||
_mockMemberPreferenceService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Get_Failure()
|
||||
{
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.GetMemberPreferencesAsync("99"))
|
||||
.Throws(new InvalidCastException()).Verifiable();
|
||||
|
||||
var result = await _controller.Get("99");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
|
||||
_mockMemberPreferenceService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Types_OK()
|
||||
{
|
||||
IReadOnlyCollection<string> values = Enum.GetValues(typeof(PreferenceType))
|
||||
.Cast<PreferenceType>()
|
||||
.Select(v => v.ToString())
|
||||
.ToList();
|
||||
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.GetAvailableTypes()).Returns(values);
|
||||
|
||||
var result = _controller.GetAvailableTypes();
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as OkObjectResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(200, okResult.StatusCode);
|
||||
|
||||
var okValue = okResult.Value as IReadOnlyCollection<string>;
|
||||
Assert.NotNull(okValue);
|
||||
Assert.IsNotEmpty(okValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_OK()
|
||||
{
|
||||
var results = new MemberOptInSettings();
|
||||
var request = new MemberPreferenceRequest
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "True",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.SaveMemberPreferenceAsync(It.IsAny<MemberPreferenceRequest>()))
|
||||
.ReturnsAsync(results);
|
||||
|
||||
var result = await _controller.CreateMemberPreference(request, "test","Associate");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var okResult = result as CreatedAtActionResult;
|
||||
Assert.NotNull(okResult);
|
||||
Assert.AreEqual(201, okResult.StatusCode);
|
||||
|
||||
Assert.AreEqual("99", okResult.RouteValues["userId"]);
|
||||
_mockMemberPreferenceService.Verify(x => x.SaveMemberPreferenceAsync(It.IsAny<MemberPreferenceRequest>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Bad_Request()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = null,
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
_controller.ModelState.AddModelError("Value", "The value field is required.");
|
||||
|
||||
// act
|
||||
var result = await _controller.CreateMemberPreference(request, "test", "Associate");
|
||||
Assert.NotNull(result);
|
||||
var badRequestResult = result as BadRequestObjectResult;
|
||||
|
||||
// assert
|
||||
Assert.NotNull(badRequestResult);
|
||||
Assert.AreEqual(StatusCodes.Status400BadRequest, badRequestResult.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Error()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "True",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.SaveMemberPreferenceAsync(It.IsAny<MemberPreferenceRequest>()))
|
||||
.ThrowsAsync(new ArithmeticException());
|
||||
|
||||
// act
|
||||
var result = await _controller.CreateMemberPreference(request, "test", "Associate");
|
||||
var badResult = result as StatusCodeResult;
|
||||
Assert.NotNull(badResult);
|
||||
Assert.AreEqual(500, badResult.StatusCode);
|
||||
|
||||
_mockMemberPreferenceService.Verify(x => x.SaveMemberPreferenceAsync(It.IsAny<MemberPreferenceRequest>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Member_Has_Hold()
|
||||
{
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "True",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
_mockMemberPreferenceService
|
||||
.Setup(service => service.SaveMemberPreferenceAsync(It.IsAny<MemberPreferenceRequest>()))
|
||||
.ThrowsAsync(new Exception());
|
||||
|
||||
var result = await _controller.CreateMemberPreference(request, "test", "Associate");
|
||||
Assert.NotNull(result);
|
||||
|
||||
var objectResult = result as StatusCodeResult;
|
||||
Assert.NotNull(objectResult);
|
||||
Assert.AreEqual(StatusCodes.Status500InternalServerError, objectResult.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Post_Bad_Request_NoHeaders()
|
||||
{
|
||||
// arrange
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "Electronic",
|
||||
UserId = "99",
|
||||
LegalReference = "None"
|
||||
};
|
||||
|
||||
// act
|
||||
var result = await _controller.CreateMemberPreference(request, null, null);
|
||||
Assert.NotNull(result);
|
||||
var badRequestResult = result as BadRequestObjectResult;
|
||||
|
||||
// assert
|
||||
Assert.NotNull(badRequestResult);
|
||||
Assert.AreEqual(StatusCodes.Status400BadRequest, badRequestResult.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
||||
<PackageReference Include="LCU.Api.Internal.FTPLib" Version="2.11.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.CoreApiWrapperModel" Version="2.27.14" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.3" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.API.Internal.MemberPreferencesApi\LCU.API.Internal.MemberPreferencesApi.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+395
@@ -0,0 +1,395 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LCU.Library.Internal.MemberPreferencesApiModels.UnitTests.Entities
|
||||
{
|
||||
public class MemberOptInSettingsTests
|
||||
{
|
||||
private MemberOptInSettings _settings;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_settings = new MemberOptInSettings();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptIn_SetsUniversalOptInAndLegalVersionAndLegalDate()
|
||||
{
|
||||
_settings.UniversalOptIn = Guid.NewGuid().ToString();
|
||||
_settings.LegalVersion = Guid.NewGuid().ToString();
|
||||
_settings.LegalDate = DateTime.MinValue;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
LegalReference = Guid.NewGuid().ToString()
|
||||
};
|
||||
var actionStart = DateTime.Now;
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
var elapsedActionTime = DateTime.Now - actionStart;
|
||||
Assert.AreEqual(preference.Value, _settings.UniversalOptIn);
|
||||
Assert.AreEqual(preference.LegalReference, _settings.LegalVersion);
|
||||
Assert.That(actionStart, Is.EqualTo(_settings.LegalDate).Within(elapsedActionTime));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptInUnchanged_DoesNotClearEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.UnifiedOptInEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.UnifiedOptInEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.UnifiedOptInEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.UnifiedOptInEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = _settings.UniversalOptIn = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(originalStatus, _settings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(originalFirstSent, _settings.UnifiedOptInEmailFirstSent);
|
||||
Assert.AreEqual(originalLastSent, _settings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(originalCount, _settings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptInChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.UniversalOptIn = Guid.NewGuid().ToString();
|
||||
_settings.UnifiedOptInEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.UnifiedOptInEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.UnifiedOptInEmailLastSent = DateTime.Now;
|
||||
_settings.UnifiedOptInEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailStatus);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailFirstSent);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptInEmail_SetsUnifiedOptInEmail()
|
||||
{
|
||||
_settings.UnifiedOptInEmail = Guid.NewGuid().ToString();
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptInEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(preference.Value, _settings.UnifiedOptInEmail);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptInEmailUnchanged_ClearsEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.UnifiedOptInEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.UnifiedOptInEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.UnifiedOptInEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.UnifiedOptInEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptInEmail,
|
||||
Value = _settings.UnifiedOptInEmail = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailStatus);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailFirstSent);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnifiedOptInEmailChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.UnifiedOptInEmail = Guid.NewGuid().ToString();
|
||||
_settings.UnifiedOptInEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.UnifiedOptInEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.UnifiedOptInEmailLastSent = DateTime.Now;
|
||||
_settings.UnifiedOptInEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptInEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailStatus);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailFirstSent);
|
||||
Assert.IsNull(_settings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotification_SetsENotifications()
|
||||
{
|
||||
_settings.ENotifications = Guid.NewGuid().ToString();
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = Guid.NewGuid().ToString()
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(preference.Value, _settings.ENotifications);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotificationsUnchanged_DoesNotClearEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.ENotificationsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.ENotificationsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.ENotificationsEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.ENotificationsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = _settings.ENotifications = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(originalStatus, _settings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(originalFirstSent, _settings.ENotificationsEmailFirstSent);
|
||||
Assert.AreEqual(originalLastSent, _settings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(originalCount, _settings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotificationsChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.ENotifications = Guid.NewGuid().ToString();
|
||||
_settings.ENotificationsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.ENotificationsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.ENotificationsEmailLastSent = DateTime.Now;
|
||||
_settings.ENotificationsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.ENotificationsEmailStatus);
|
||||
Assert.IsNull(_settings.ENotificationsEmailFirstSent);
|
||||
Assert.IsNull(_settings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotificationsEmail_SetsENotificationsEmail()
|
||||
{
|
||||
_settings.ENotificationsEmail = Guid.NewGuid().ToString();
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotificationsEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(preference.Value, _settings.ENotificationsEmail);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotificationsEmailUnchanged_ClearsEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.ENotificationsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.ENotificationsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.ENotificationsEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.ENotificationsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotificationsEmail,
|
||||
Value = _settings.ENotificationsEmail = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.ENotificationsEmailStatus);
|
||||
Assert.IsNull(_settings.ENotificationsEmailFirstSent);
|
||||
Assert.IsNull(_settings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_ENotificationsEmailChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.ENotificationsEmail = Guid.NewGuid().ToString();
|
||||
_settings.ENotificationsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.ENotificationsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.ENotificationsEmailLastSent = DateTime.Now;
|
||||
_settings.ENotificationsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.ENotificationsEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.ENotificationsEmailStatus);
|
||||
Assert.IsNull(_settings.ENotificationsEmailFirstSent);
|
||||
Assert.IsNull(_settings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatements_SetsEStatements()
|
||||
{
|
||||
_settings.EStatements = Guid.NewGuid().ToString();
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = Guid.NewGuid().ToString()
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(preference.Value, _settings.EStatements);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatementsUnchanged_DoesNotClearEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.EStatementsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.EStatementsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.EStatementsEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.EStatementsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = _settings.EStatements = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(originalStatus, _settings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(originalFirstSent, _settings.EStatementsEmailFirstSent);
|
||||
Assert.AreEqual(originalLastSent, _settings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(originalCount, _settings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatementsChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.EStatements = Guid.NewGuid().ToString();
|
||||
_settings.EStatementsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.EStatementsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.EStatementsEmailLastSent = DateTime.Now;
|
||||
_settings.EStatementsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.EStatementsEmailStatus);
|
||||
Assert.IsNull(_settings.EStatementsEmailFirstSent);
|
||||
Assert.IsNull(_settings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatementsEmail_SetsEStatementsEmail()
|
||||
{
|
||||
_settings.EStatementsEmail = Guid.NewGuid().ToString();
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatementsEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.AreEqual(preference.Value, _settings.EStatementsEmail);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatementsEmailUnchanged_ClearsEmailTracking()
|
||||
{
|
||||
var originalStatus = _settings.EStatementsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
var originalFirstSent = _settings.EStatementsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
var originalLastSent = _settings.EStatementsEmailLastSent = DateTime.Now;
|
||||
var originalCount = _settings.EStatementsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatementsEmail,
|
||||
Value = _settings.EStatementsEmail = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.EStatementsEmailStatus);
|
||||
Assert.IsNull(_settings.EStatementsEmailFirstSent);
|
||||
Assert.IsNull(_settings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_EStatementsEmailChanged_ClearsEmailTracking()
|
||||
{
|
||||
_settings.EStatementsEmail = Guid.NewGuid().ToString();
|
||||
_settings.EStatementsEmailStatus = RandomEnumValueFactory<EmailStatus>();
|
||||
_settings.EStatementsEmailFirstSent = DateTime.Now.AddHours(-1);
|
||||
_settings.EStatementsEmailLastSent = DateTime.Now;
|
||||
_settings.EStatementsEmailStatusCount = DateTime.Now.Millisecond;
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.EStatementsEmail,
|
||||
Value = Guid.NewGuid().ToString(),
|
||||
};
|
||||
|
||||
_settings.Apply(preference);
|
||||
|
||||
Assert.IsNull(_settings.EStatementsEmailStatus);
|
||||
Assert.IsNull(_settings.EStatementsEmailFirstSent);
|
||||
Assert.IsNull(_settings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(0, _settings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Apply_UnknownPreference_ThrowsException()
|
||||
{
|
||||
var preference = new MemberPreference
|
||||
{
|
||||
Preference = (PreferenceType)(Enum.GetValues(typeof(PreferenceType)).Length + 1)
|
||||
};
|
||||
|
||||
var thrown = Assert.Throws<InvalidOperationException>(() => _settings.Apply(preference));
|
||||
|
||||
StringAssert.Contains(preference.Preference.ToString(), thrown?.Message);
|
||||
}
|
||||
|
||||
private static T RandomEnumValueFactory<T>()
|
||||
where T : Enum
|
||||
{
|
||||
var values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
|
||||
|
||||
return values[DateTime.Now.Millisecond % values.Length];
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.Library.Internal.MemberPreferencesApiModels.UnitTests.Policies.Email.FailedToSend
|
||||
{
|
||||
public class EStatementsSixtyDaysUndeliverableEmailPolicyTest : SixtyDaysUndeliverableEmailPolicyTest
|
||||
{
|
||||
protected override SixtyDaysUndeliverableEmailPolicy Policy { get; }
|
||||
|
||||
public EStatementsSixtyDaysUndeliverableEmailPolicyTest()
|
||||
{
|
||||
Policy = new EStatementsSixtyDaysUndeliverableEmailPolicy(AuditableChanges, MemberPreferences);
|
||||
}
|
||||
|
||||
protected override void SetEmailStatus(MemberOptInSettings settings, EmailStatus status)
|
||||
=> settings.EStatementsEmailStatus = status;
|
||||
protected override void SetFirstSent(MemberOptInSettings settings, DateTime firstSent)
|
||||
=> settings.EStatementsEmailFirstSent = firstSent;
|
||||
protected override void SetLastSend(MemberOptInSettings settings, DateTime lastSent)
|
||||
=> settings.EStatementsEmailLastSent = lastSent;
|
||||
protected override void SetEligibleForPreferenceFlip(MemberOptInSettings settings)
|
||||
=> settings.UniversalOptIn = null;
|
||||
protected override string GetPreference(MemberOptInSettings settings)
|
||||
=> settings.UniversalOptIn;
|
||||
}
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Models;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
|
||||
namespace LCU.Library.Internal.MemberPreferencesApiModels.UnitTests.Policies.Email.FailedToSend
|
||||
{
|
||||
public abstract class SixtyDaysUndeliverableEmailPolicyTest
|
||||
{
|
||||
protected abstract SixtyDaysUndeliverableEmailPolicy Policy { get; }
|
||||
protected IAuditableChanges AuditableChanges => _auditableChanges;
|
||||
protected IMemberPreferences MemberPreferences => _memberPreferences;
|
||||
|
||||
protected abstract void SetEmailStatus(MemberOptInSettings settings, EmailStatus status);
|
||||
protected abstract void SetFirstSent(MemberOptInSettings settings, DateTime firstSent);
|
||||
protected abstract void SetLastSend(MemberOptInSettings settings, DateTime lastSent);
|
||||
protected abstract void SetEligibleForPreferenceFlip(MemberOptInSettings settings);
|
||||
protected abstract string GetPreference(MemberOptInSettings settings);
|
||||
|
||||
private readonly FakeAuditableChanges _auditableChanges = new FakeAuditableChanges();
|
||||
private readonly FakeMemberPreferences _memberPreferences = new FakeMemberPreferences();
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_memberPreferences.Changes.Clear();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Apply_NotFailingDelivery_ReturnsFalse()
|
||||
{
|
||||
var settings = SettingsFactory();
|
||||
SetEmailStatus(settings, EmailStatus.DeliveredSuccessfully);
|
||||
var originalSettings = Clone(settings);
|
||||
var anyChanges = await Policy.Apply(settings, true);
|
||||
|
||||
Assert.That(anyChanges, Is.False);
|
||||
Assert.That(_memberPreferences.Changes.Any(), Is.False);
|
||||
settings.Should().BeEquivalentTo(originalSettings);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Apply_FailingDeliveryForLessThanSixtyDays_ReturnsFalse()
|
||||
{
|
||||
var settings = SettingsFactory();
|
||||
SetEmailStatus(settings, EmailStatus.FailingDelivery);
|
||||
SetFirstSent(settings, DateTime.Now.AddDays(-59));
|
||||
SetLastSend(settings, DateTime.Now);
|
||||
var originalSettings = Clone(settings);
|
||||
var anyChanges = await Policy.Apply(settings, true);
|
||||
Assert.That(anyChanges, Is.False);
|
||||
Assert.That(_memberPreferences.Changes.Any(), Is.False);
|
||||
settings.Should().BeEquivalentTo(originalSettings);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Apply_FailingDeliveryForSixtyDaysOrMore_ReturnsTrueAndSetsToPaper()
|
||||
{
|
||||
var settings = SettingsFactory();
|
||||
SetEmailStatus(settings, EmailStatus.FailingDelivery);
|
||||
SetFirstSent(settings, DateTime.Now.AddDays(-60));
|
||||
SetLastSend(settings, DateTime.Now);
|
||||
SetEligibleForPreferenceFlip(settings);
|
||||
|
||||
var originalSettings = Clone(settings);
|
||||
var anyChanges = await Policy.Apply(settings, true);
|
||||
|
||||
var preference = GetPreference(settings);
|
||||
Assert.That(anyChanges, Is.True);
|
||||
settings.Should().BeEquivalentTo
|
||||
(
|
||||
originalSettings,
|
||||
except => except
|
||||
.Excluding(s => s.LastUpdatedBy)
|
||||
.Excluding(s => s.UniversalOptIn)
|
||||
.Excluding(s => s.ENotifications)
|
||||
.Excluding(s => s.EStatements)
|
||||
);
|
||||
Assert.That(preference, Is.EqualTo(DeliveryPreference.Paper));
|
||||
Assert.That(settings.LastUpdatedBy, Is.EqualTo("BounceBackLimitReached"));
|
||||
Assert.That(_memberPreferences.Changes.Count(p => p.Value == DeliveryPreference.Paper && p.UserId == settings.UserId && p.LastUpdatedBy == "BounceBackLimitReached"), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Apply_FailingDeliveryForSixtyDaysOrMore_FeatureFlagReturnsFalse()
|
||||
{
|
||||
var settings = SettingsFactory();
|
||||
SetEmailStatus(settings, EmailStatus.FailingDelivery);
|
||||
SetFirstSent(settings, DateTime.Now.AddDays(-60));
|
||||
SetLastSend(settings, DateTime.Now);
|
||||
var originalSettings = Clone(settings);
|
||||
var anyChanges = await Policy.Apply(settings, false);
|
||||
var preference = GetPreference(settings);
|
||||
|
||||
Assert.That(anyChanges, Is.False);
|
||||
Assert.That(_memberPreferences.Changes.Any(), Is.False);
|
||||
settings.Should().BeEquivalentTo(originalSettings);
|
||||
Assert.That(_memberPreferences.Changes.Count(p => p.Value == DeliveryPreference.Paper && p.UserId == settings.UserId && p.LastUpdatedBy == "BounceBackLimitReached"), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Apply_FailingDeliveryForSixtyDaysOrMore_SetsTrackingToBounceBackSystem()
|
||||
{
|
||||
var settings = SettingsFactory();
|
||||
SetEmailStatus(settings, EmailStatus.FailingDelivery);
|
||||
SetFirstSent(settings, DateTime.Now.AddDays(-60));
|
||||
SetLastSend(settings, DateTime.Now);
|
||||
SetEligibleForPreferenceFlip(settings);
|
||||
await Policy.Apply(settings, true);
|
||||
|
||||
Assert.That(settings.LastUpdatedBy, Is.EqualTo("BounceBackLimitReached"));
|
||||
Assert.That(_auditableChanges.SystemModifiedAuditableEntities.ContainsKey(settings), Is.True);
|
||||
Assert.That(_auditableChanges.SystemModifiedAuditableEntities[settings], Is.EqualTo("BounceBackLimitReached"));
|
||||
}
|
||||
|
||||
private static MemberOptInSettings SettingsFactory()
|
||||
=> new MemberOptInSettings
|
||||
{
|
||||
LastUpdatedBy = Guid.NewGuid().ToString(),
|
||||
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmailStatus = EmailStatus.DeliveredSuccessfully,
|
||||
UnifiedOptInEmailFirstSent = DateTime.Now,
|
||||
UnifiedOptInEmailLastSent = DateTime.Now,
|
||||
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmailStatus = EmailStatus.DeliveredSuccessfully,
|
||||
ENotificationsEmailFirstSent = DateTime.Now,
|
||||
ENotificationsEmailLastSent = DateTime.Now,
|
||||
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmailStatus = EmailStatus.DeliveredSuccessfully,
|
||||
EStatementsEmailFirstSent = DateTime.Now,
|
||||
EStatementsEmailLastSent = DateTime.Now
|
||||
};
|
||||
|
||||
private static MemberOptInSettings Clone(MemberOptInSettings settings)
|
||||
=> new MemberOptInSettings
|
||||
{
|
||||
LastUpdatedBy = settings.LastUpdatedBy,
|
||||
|
||||
UniversalOptIn = settings.UniversalOptIn,
|
||||
UnifiedOptInEmailStatus = settings.UnifiedOptInEmailStatus,
|
||||
UnifiedOptInEmailFirstSent = settings.UnifiedOptInEmailFirstSent,
|
||||
UnifiedOptInEmailLastSent = settings.UnifiedOptInEmailLastSent,
|
||||
|
||||
ENotifications = settings.ENotifications,
|
||||
ENotificationsEmailStatus = settings.ENotificationsEmailStatus,
|
||||
ENotificationsEmailFirstSent = settings.ENotificationsEmailFirstSent,
|
||||
ENotificationsEmailLastSent = settings.ENotificationsEmailLastSent,
|
||||
|
||||
EStatements = settings.EStatements,
|
||||
EStatementsEmailStatus = settings.EStatementsEmailStatus,
|
||||
EStatementsEmailFirstSent = settings.EStatementsEmailFirstSent,
|
||||
EStatementsEmailLastSent = settings.EStatementsEmailLastSent
|
||||
};
|
||||
|
||||
private class FakeAuditableChanges : IAuditableChanges
|
||||
{
|
||||
public IDictionary<Auditable, string> SystemModifiedAuditableEntities { get; } =
|
||||
new Dictionary<Auditable, string>();
|
||||
|
||||
public void SystemModified(Auditable entity, string modifiedBy)
|
||||
{
|
||||
SystemModifiedAuditableEntities[entity] = modifiedBy;
|
||||
}
|
||||
}
|
||||
|
||||
private class FakeMemberPreferences : IMemberPreferences
|
||||
{
|
||||
public IList<MemberPreference> Changes { get; }= new List<MemberPreference>();
|
||||
|
||||
public Task Add(MemberPreference preferenceChange)
|
||||
{
|
||||
Changes.Add(preferenceChange);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.Library.Internal.MemberPreferencesApiModels.UnitTests.Policies.Email.FailedToSend
|
||||
{
|
||||
public class UnifiedSixtyDaysUndeliverableEmailPolicyTest : SixtyDaysUndeliverableEmailPolicyTest
|
||||
{
|
||||
protected override SixtyDaysUndeliverableEmailPolicy Policy { get; }
|
||||
|
||||
public UnifiedSixtyDaysUndeliverableEmailPolicyTest()
|
||||
{
|
||||
Policy= new UnifiedSixtyDaysUndeliverableEmailPolicy(AuditableChanges, MemberPreferences);
|
||||
}
|
||||
|
||||
protected override void SetEmailStatus(MemberOptInSettings settings, EmailStatus status)
|
||||
=> settings.UnifiedOptInEmailStatus = status;
|
||||
protected override void SetFirstSent(MemberOptInSettings settings, DateTime firstSent)
|
||||
=> settings.UnifiedOptInEmailFirstSent = firstSent;
|
||||
protected override void SetLastSend(MemberOptInSettings settings, DateTime lastSent)
|
||||
=> settings.UnifiedOptInEmailLastSent = lastSent;
|
||||
protected override void SetEligibleForPreferenceFlip(MemberOptInSettings settings)
|
||||
=> settings.UniversalOptIn = "Electronic";
|
||||
protected override string GetPreference(MemberOptInSettings settings)
|
||||
=> settings.UniversalOptIn;
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Infrastructure.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Persistence;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Repository
|
||||
{
|
||||
public class DnaAuditProcessRepositoryTest
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
private DnaAuditProcessRepository _repository;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var mockDateTime = new DateTimeService();
|
||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.EnableSensitiveDataLogging()
|
||||
.Options;
|
||||
_context = new ApplicationDbContext(options);
|
||||
_repository = new DnaAuditProcessRepository(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Basic_Flow_Test()
|
||||
{
|
||||
var saved = await _repository.GetAllDnaAuditProcesses();
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsEmpty(saved);
|
||||
|
||||
var dnaProcess = new DnaAuditProcess()
|
||||
{
|
||||
ProcessId = 1,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAccounts,
|
||||
LastUpdated = DateTime.Now,
|
||||
ConsecutiveFailures = 2
|
||||
};
|
||||
await _context.AddAsync(dnaProcess);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
saved = await _repository.GetAllDnaAuditProcesses();
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
var first = saved.First();
|
||||
|
||||
Assert.AreEqual(first.ConsecutiveFailures, 2);
|
||||
Assert.AreEqual(first.DnaProcessType, DnaAuditProcessType.DNAAccounts);
|
||||
Assert.AreEqual(first.ProcessId, 1);
|
||||
|
||||
dnaProcess.DnaProcessType = DnaAuditProcessType.DNAOrganization;
|
||||
dnaProcess.ConsecutiveFailures = 0;
|
||||
await _repository.Update(dnaProcess);
|
||||
|
||||
saved = await _repository.GetAllDnaAuditProcesses();
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
first = saved.First();
|
||||
|
||||
Assert.AreEqual(first.ConsecutiveFailures, 0);
|
||||
Assert.AreEqual(first.DnaProcessType, DnaAuditProcessType.DNAOrganization);
|
||||
Assert.AreEqual(first.ProcessId, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Infrastructure.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Persistence;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Repository
|
||||
{
|
||||
public class MemberPreferenceRepositoryTest
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
private MemberPreferenceRepository _repository;
|
||||
private UnifiedOptInRepository _optInRepository;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var mockDateTime = new DateTimeService();
|
||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.EnableSensitiveDataLogging()
|
||||
.Options;
|
||||
_context = new ApplicationDbContext(options);
|
||||
_repository = new MemberPreferenceRepository(_context);
|
||||
_optInRepository = new UnifiedOptInRepository(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Basic_Flow_Test()
|
||||
{
|
||||
var saved = await _repository.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsEmpty(saved);
|
||||
|
||||
await _repository.SaveMemberPreferenceAsync(new MemberPreference
|
||||
{
|
||||
UserId = "99",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "True"
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
saved = await _repository.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
var first = saved.First();
|
||||
// Make sure our Auditable is working.
|
||||
Assert.NotNull(first.CreatedBy);
|
||||
Assert.NotNull(first.Created);
|
||||
Assert.NotNull(first.LastUpdatedBy);
|
||||
Assert.NotNull(first.LastUpdated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Bulk_Flow_Test()
|
||||
{
|
||||
var memberResult = await _optInRepository.GetMemberOptInSettings("99");
|
||||
Assert.Null(memberResult);
|
||||
|
||||
var listOfPreferences = new List<MemberPreference>
|
||||
{
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "99",
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = "True"
|
||||
},
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = "True"
|
||||
},
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "101",
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = "True"
|
||||
}
|
||||
};
|
||||
|
||||
await _repository.BulkSaveMemberPreferenceAsync(listOfPreferences);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var saved = await _repository.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
var first = saved.First();
|
||||
// Make sure our Auditable is working.
|
||||
Assert.NotNull(first.CreatedBy);
|
||||
Assert.NotNull(first.Created);
|
||||
Assert.NotNull(first.LastUpdatedBy);
|
||||
Assert.NotNull(first.LastUpdated);
|
||||
|
||||
saved = await _repository.GetMemberPreferencesAsync("100");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
first = saved.First();
|
||||
// Make sure our Auditable is working.
|
||||
Assert.NotNull(first.CreatedBy);
|
||||
Assert.NotNull(first.Created);
|
||||
Assert.NotNull(first.LastUpdatedBy);
|
||||
Assert.NotNull(first.LastUpdated);
|
||||
|
||||
saved = await _repository.GetMemberPreferencesAsync("101");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
first = saved.First();
|
||||
// Make sure our Auditable is working.
|
||||
Assert.NotNull(first.CreatedBy);
|
||||
Assert.NotNull(first.Created);
|
||||
Assert.NotNull(first.LastUpdatedBy);
|
||||
Assert.NotNull(first.LastUpdated);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("99");
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("True", memberResult.EStatements);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("100");
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("True", memberResult.EStatements);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("101");
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("True", memberResult.EStatements);
|
||||
|
||||
listOfPreferences = new List<MemberPreference>
|
||||
{
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "99",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "Yes"
|
||||
},
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "Yes"
|
||||
},
|
||||
new MemberPreference
|
||||
{
|
||||
UserId = "101",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "Yes"
|
||||
}
|
||||
};
|
||||
|
||||
await _repository.BulkSaveMemberPreferenceAsync(listOfPreferences);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("99");
|
||||
Assert.AreEqual(1, saved.Count);
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("Yes", memberResult.ENotifications);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("100");
|
||||
Assert.AreEqual(1, saved.Count);
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("Yes", memberResult.ENotifications);
|
||||
|
||||
memberResult = await _optInRepository.GetMemberOptInSettings("101");
|
||||
Assert.AreEqual(1, saved.Count);
|
||||
Assert.NotNull(memberResult);
|
||||
Assert.AreEqual("Yes", memberResult.ENotifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Infrastructure.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Persistence;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Repository
|
||||
{
|
||||
public class UnifiedOptInRepositoryTest
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
private UnifiedOptInRepository _optInRepository;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var mockDateTime = new DateTimeService();
|
||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.EnableSensitiveDataLogging()
|
||||
.Options;
|
||||
_context = new ApplicationDbContext(options);
|
||||
_optInRepository = new UnifiedOptInRepository(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Basic_Flow_Test()
|
||||
{
|
||||
var memberResult = await _optInRepository.GetMemberOptInSettings("99");
|
||||
Assert.Null(memberResult);
|
||||
|
||||
memberResult = await _optInRepository.GetOrCreateMemberOptinSettings("99");
|
||||
await _context.SaveChangesAsync();
|
||||
Assert.NotNull(memberResult);
|
||||
|
||||
// Make sure our Auditable is working.
|
||||
Assert.NotNull(memberResult.CreatedBy);
|
||||
Assert.NotNull(memberResult.Created);
|
||||
Assert.NotNull(memberResult.LastUpdatedBy);
|
||||
Assert.NotNull(memberResult.LastUpdated);
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Interfaces;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class DNADataAuditProcessServiceTest
|
||||
{
|
||||
private Mock<ICoreApiWrapperService> _coreApiWrapperServiceMock;
|
||||
private Mock<IQueueDnaAccountAuditService> _queueAccountMock;
|
||||
private Mock<IQueueDnaAgreementAuditService> _queueAgreementMock;
|
||||
private Mock<IQueueDnaOrganizationAuditService> _queueOrganizationMock;
|
||||
private Mock<IDnaAuditProcessRepository> _dnaAuditProcessRepositoryMock;
|
||||
private DNADataAuditProcessService _service;
|
||||
private Mock<IDateTime> _dateTimeMock;
|
||||
private DnaAuditProcessConfiguration _config;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_dateTimeMock = new Mock<IDateTime>();
|
||||
_config = new DnaAuditProcessConfiguration();
|
||||
_coreApiWrapperServiceMock = new Mock<ICoreApiWrapperService>();
|
||||
_queueAccountMock = new Mock<IQueueDnaAccountAuditService>();
|
||||
_queueAgreementMock = new Mock<IQueueDnaAgreementAuditService>();
|
||||
_queueOrganizationMock = new Mock<IQueueDnaOrganizationAuditService>();
|
||||
_dnaAuditProcessRepositoryMock = new Mock<IDnaAuditProcessRepository>();
|
||||
_service = new DNADataAuditProcessService(_queueAccountMock.Object, _queueAgreementMock.Object, _queueOrganizationMock.Object,
|
||||
_coreApiWrapperServiceMock.Object, _dateTimeMock.Object, _dnaAuditProcessRepositoryMock.Object, _config);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RunDnaAuditProcessesChange_HandleProcessUpdate_Ok()
|
||||
{
|
||||
|
||||
var processlistAccount = new List<DnaAuditProcess>
|
||||
{
|
||||
new DnaAuditProcess()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAccounts,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 0,
|
||||
}
|
||||
};
|
||||
|
||||
var processlistAgreement = new List<DnaAuditProcess>
|
||||
{
|
||||
new DnaAuditProcess()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAgreement,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 0,
|
||||
}
|
||||
};
|
||||
|
||||
var processlistOrg = new List<DnaAuditProcess>
|
||||
{
|
||||
new DnaAuditProcess()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaProcessType = DnaAuditProcessType.DNAOrganization,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 0,
|
||||
}
|
||||
};
|
||||
|
||||
await _service.RunDataAuditProcesses();
|
||||
await _service.AuditDNAAccountsForTimePeriod(DateTime.Now, processlistAccount.First());
|
||||
var resultAccount = _service.HandleDnaAuditProcessSuccess(processlistAccount.First());
|
||||
|
||||
await _service.AuditDNAAgreementForTimePeriod(DateTime.Now, processlistAgreement.First());
|
||||
var resultAgreement = _service.HandleDnaAuditProcessSuccess(processlistAgreement.First());
|
||||
|
||||
await _service.AuditDNAOrganizationForTimePeriod(DateTime.Now, processlistOrg.First());
|
||||
var resultOrg = _service.HandleDnaAuditProcessSuccess(processlistOrg.First());
|
||||
|
||||
//assert
|
||||
Assert.NotNull(resultAccount);
|
||||
Assert.AreEqual(resultAccount.DnaProcessType, DnaAuditProcessType.DNAAccounts);
|
||||
Assert.AreEqual(resultAccount.ConsecutiveFailures, 0);
|
||||
|
||||
Assert.NotNull(resultAgreement);
|
||||
Assert.AreEqual(resultAgreement.DnaProcessType, DnaAuditProcessType.DNAAgreement);
|
||||
Assert.AreEqual(resultAgreement.ConsecutiveFailures, 0);
|
||||
|
||||
Assert.NotNull(resultOrg);
|
||||
Assert.AreEqual(resultOrg.DnaProcessType, DnaAuditProcessType.DNAOrganization);
|
||||
Assert.AreEqual(resultOrg.ConsecutiveFailures, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RunDnaAuditProcessesChange_HandleProcessUpdateException_Ok()
|
||||
{
|
||||
|
||||
var processlistAccount = new List<DnaAuditProcess>
|
||||
{
|
||||
new DnaAuditProcess()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAccounts,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 0,
|
||||
}
|
||||
};
|
||||
|
||||
var ex = new Exception();
|
||||
await _service.RunDataAuditProcesses();
|
||||
await _service.AuditDNAAccountsForTimePeriod(DateTime.Now, processlistAccount.First());
|
||||
var resultAccount = _service.HandleDnaAuditProcessException(processlistAccount.First(), ex);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(resultAccount);
|
||||
Assert.AreEqual(resultAccount.DnaProcessType, DnaAuditProcessType.DNAAccounts);
|
||||
Assert.AreEqual(resultAccount.ConsecutiveFailures, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.Requests;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class DNADataAuditServiceTest
|
||||
{
|
||||
private Mock<ICoreApiWrapperService> _coreApiWrapperServiceMock;
|
||||
private Mock<IOptinService> _optinServiceMock;
|
||||
private DNADataAuditService _service;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_coreApiWrapperServiceMock = new Mock<ICoreApiWrapperService>();
|
||||
_optinServiceMock = new Mock<IOptinService>();
|
||||
_service = new DNADataAuditService(_coreApiWrapperServiceMock.Object, _optinServiceMock.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task HandleChangedFields_AccountChange_OK_UPDATE()
|
||||
{
|
||||
|
||||
var account = new AgreementAccount
|
||||
{
|
||||
AccountNumber = 123456,
|
||||
OvrDeliveryMethCD = "PRNT",
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123456,
|
||||
AgreementNumber = 222,
|
||||
PersonNumber = 123,
|
||||
UserId = "1234"
|
||||
}
|
||||
};
|
||||
|
||||
var memberOptinSettings = new MemberOptInSettings
|
||||
{
|
||||
EStatements = null,
|
||||
UniversalOptIn = "Electronic"
|
||||
};
|
||||
|
||||
//setup
|
||||
_coreApiWrapperServiceMock.Setup(x => x.GetAgreementAccountByAccountId(123456)).ReturnsAsync(account).Verifiable();
|
||||
|
||||
_optinServiceMock.Setup(x => x.GetMemberOptInSettings("1234")).ReturnsAsync(memberOptinSettings).Verifiable();
|
||||
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaFieldIdInformation = 123456L,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAgreement,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 1
|
||||
};
|
||||
|
||||
await _service.HandleAccountAuditCheck(request);
|
||||
|
||||
//assert
|
||||
_coreApiWrapperServiceMock.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(list => list.Contains(123456)), It.Is<string>(x => x.Equals("WWW")), It.Is<string>(x => x.Equals("1234"))), Times.Once);
|
||||
_coreApiWrapperServiceMock.Verify();
|
||||
_optinServiceMock.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task HandleChangedFields_AccountChange_OK_DONTUPDATE()
|
||||
{
|
||||
var account = new AgreementAccount
|
||||
{
|
||||
AccountNumber = 123456,
|
||||
OvrDeliveryMethCD = "PRNT",
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123456,
|
||||
AgreementNumber = 222,
|
||||
PersonNumber = 123,
|
||||
UserId = "1234"
|
||||
}
|
||||
};
|
||||
|
||||
var memberOptinSettings = new MemberOptInSettings
|
||||
{
|
||||
EStatements = null,
|
||||
UniversalOptIn = "Paper"
|
||||
};
|
||||
|
||||
//setup
|
||||
_coreApiWrapperServiceMock.Setup(x => x.GetAgreementAccountByAccountId(123456)).ReturnsAsync(account).Verifiable();
|
||||
|
||||
_optinServiceMock.Setup(x => x.GetMemberOptInSettings("1234"))
|
||||
.ReturnsAsync(memberOptinSettings).Verifiable();
|
||||
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaFieldIdInformation = 123456L,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAccounts,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 1
|
||||
};
|
||||
|
||||
await _service.HandleAccountAuditCheck(request);
|
||||
|
||||
//assert
|
||||
_coreApiWrapperServiceMock.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.IsAny<List<long>>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
_coreApiWrapperServiceMock.Verify();
|
||||
_optinServiceMock.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task HandleChangedFields_AgreementChange_OK_UPDATE()
|
||||
{
|
||||
var agreement = new Agreement
|
||||
{
|
||||
AgreementNumber = 1127,
|
||||
PersonNumber = 123,
|
||||
UserId = "1234"
|
||||
};
|
||||
|
||||
var accounts = new List<AgreementAccount>
|
||||
{
|
||||
new AgreementAccount{
|
||||
AccountNumber = 123456,
|
||||
OvrDeliveryMethCD = "PRNT",
|
||||
TaxReportForPersonNumber = 123,
|
||||
AccountOwner = new AgreementAccountOwner{
|
||||
AccountNumber = 123456,
|
||||
AgreementNumber = 1127,
|
||||
PersonNumber = 123,
|
||||
UserId = "1234"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var memberOptinSettings = new MemberOptInSettings
|
||||
{
|
||||
EStatements = null,
|
||||
UniversalOptIn = "Electronic"
|
||||
};
|
||||
|
||||
//setup
|
||||
_coreApiWrapperServiceMock.Setup(x => x.GetAgreementByAgreementId(1127)).ReturnsAsync(agreement).Verifiable();
|
||||
_coreApiWrapperServiceMock.Setup(x => x.GetAgreementAccountsByUserId("1234")).ReturnsAsync(accounts).Verifiable();
|
||||
|
||||
_optinServiceMock.Setup(x => x.GetMemberOptInSettings("1234")).ReturnsAsync(memberOptinSettings).Verifiable();
|
||||
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaFieldIdInformation = 1127L,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAgreement,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 1
|
||||
};
|
||||
|
||||
await _service.HandleAgreementAuditCheck(request);
|
||||
|
||||
//assert
|
||||
_coreApiWrapperServiceMock.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(list => list.Contains(123456)), It.Is<string>(x => x.Equals("WWW")), It.Is<string>(x => x.Equals("1234"))), Times.Once);
|
||||
_coreApiWrapperServiceMock.Verify();
|
||||
_optinServiceMock.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task HandleChangedFields_OrganizationChange_OK_UPDATE()
|
||||
{
|
||||
var accounts = new List<AgreementAccount>
|
||||
{
|
||||
new AgreementAccount{
|
||||
AccountNumber = 123456,
|
||||
TaxReportForOrgNumber = 11267,
|
||||
OvrDeliveryMethCD = "PRNT",
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123456,
|
||||
AgreementNumber = 222,
|
||||
PersonNumber = 123,
|
||||
UserId = "1234"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var memberOptinSettings = new MemberOptInSettings
|
||||
{
|
||||
EStatements = null,
|
||||
UniversalOptIn = "Electronic"
|
||||
};
|
||||
|
||||
//setup
|
||||
|
||||
_coreApiWrapperServiceMock.Setup(x => x.GetAgreementAccountsByOrganizationId(1126)).ReturnsAsync(accounts).Verifiable();
|
||||
|
||||
_optinServiceMock.Setup(x => x.GetMemberOptInSettings("1234")).ReturnsAsync(memberOptinSettings).Verifiable();
|
||||
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
ConsecutiveFailures = 0,
|
||||
DnaFieldIdInformation = 1126L,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAgreement,
|
||||
LastUpdated = DateTime.Now,
|
||||
ProcessId = 1
|
||||
};
|
||||
|
||||
//act
|
||||
await _service.HandleOrganizationAuditCheck(request);
|
||||
|
||||
//assert
|
||||
_coreApiWrapperServiceMock.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(list => list.Contains(123456)), It.Is<string>(x => x.Equals("WWW")), It.Is<string>(x => x.Equals("1234"))), Times.Once);
|
||||
_coreApiWrapperServiceMock.Verify();
|
||||
_optinServiceMock.Verify();
|
||||
}
|
||||
}
|
||||
}
|
||||
+882
@@ -0,0 +1,882 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class MemberEmailServiceTest
|
||||
{
|
||||
private readonly IMemberEmailService _service;
|
||||
|
||||
private readonly FakeUnifiedOptInRepository _repository;
|
||||
|
||||
private readonly Mock<IIntegrationService> _mockIntegrationService;
|
||||
|
||||
private readonly Mock<IMemberPreferenceService> _mockPreferenceService;
|
||||
|
||||
private readonly Mock<IEmailFailurePolicy>[] _policies =
|
||||
{
|
||||
new Mock<IEmailFailurePolicy>(),
|
||||
new Mock<IEmailFailurePolicy>()
|
||||
};
|
||||
|
||||
public MemberEmailServiceTest()
|
||||
{
|
||||
var unitOfWork = new FakeUnitOfWork();
|
||||
_repository = new FakeUnifiedOptInRepository(unitOfWork);
|
||||
_mockIntegrationService = new Mock<IIntegrationService>();
|
||||
_mockPreferenceService = new Mock<IMemberPreferenceService>();
|
||||
|
||||
_service = new MemberEmailService(_repository, unitOfWork, _policies.Select(p => p.Object), _mockPreferenceService.Object, _mockIntegrationService.Object);
|
||||
}
|
||||
|
||||
private static readonly (DateTime? firstSent, DateTime? lastSent, EmailStatus PriorStatus, int count)[]
|
||||
PreUpdateStateScenarios =
|
||||
{
|
||||
(null, null, EmailStatus.FailingDelivery, 1),
|
||||
(DateTime.Now.AddHours(-2), null, EmailStatus.FailingDelivery, 2),
|
||||
(null, DateTime.Now.AddHours(-3), EmailStatus.FailingDelivery, 3),
|
||||
(DateTime.Now.AddHours(-4), DateTime.Now.AddHours(-4), EmailStatus.FailingDelivery, 4),
|
||||
(null, null, EmailStatus.DeliveredSuccessfully, 5),
|
||||
(DateTime.Now.AddHours(-6), null, EmailStatus.DeliveredSuccessfully, 6),
|
||||
(null, DateTime.Now.AddHours(-7), EmailStatus.DeliveredSuccessfully, 7),
|
||||
(DateTime.Now.AddHours(-8), DateTime.Now.AddHours(-8), EmailStatus.DeliveredSuccessfully, 8),
|
||||
};
|
||||
|
||||
private static readonly (bool isUnifiedOptIn, bool matchesUnifiedOptin, bool matchesENotification, bool matchesEstatement)[]
|
||||
MatchScenarios =
|
||||
{
|
||||
(true, true, true, true),
|
||||
(true, true, true, false),
|
||||
(true, true, false, true),
|
||||
(true, true, false, false),
|
||||
(false, false, true, true),
|
||||
(false, false, true, false),
|
||||
(false, false, false, true),
|
||||
(false, false, true, true),
|
||||
(false, false, true, false),
|
||||
(false, false, false, true),
|
||||
};
|
||||
|
||||
private static IEnumerable<object> CombinedScenarios()
|
||||
{
|
||||
foreach (var match in MatchScenarios)
|
||||
{
|
||||
foreach (var state in PreUpdateStateScenarios)
|
||||
{
|
||||
yield return new UpdateScenario(state, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly object[] UpdateScenarios = CombinedScenarios().ToArray();
|
||||
|
||||
private static readonly Random Random = new Random(DateTime.Now.Millisecond);
|
||||
private static string EmailAddressFactory()
|
||||
{
|
||||
static char RandomLetter() => (char)('a' + Random.Next(0, 26));
|
||||
|
||||
return string.Concat
|
||||
(
|
||||
Enumerable.Repeat<Func<char>>(RandomLetter, Random.Next(5, 50)).Select(f => f())
|
||||
)
|
||||
.RandomizeCase();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSucceededToSend_UserOptInSettingsNotFound_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings.Remove(userId);
|
||||
|
||||
var updated = await _service.EmailSucceededToSend(userId, Guid.NewGuid().ToString());
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSucceededToSend_NoEmailMatches_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = EmailAddressFactory(),
|
||||
EStatementsEmail = EmailAddressFactory(),
|
||||
ENotificationsEmail = EmailAddressFactory()
|
||||
};
|
||||
|
||||
var updated = await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailSucceededToSend_NullEmailNoMatches_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = EmailAddressFactory(),
|
||||
EStatementsEmail = EmailAddressFactory(),
|
||||
ENotificationsEmail = EmailAddressFactory()
|
||||
};
|
||||
|
||||
var updated = await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailSucceededToSend_EmailMatchesRegardlessOfCase_ReturnsTrue(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = scenario.MatchScenario.matchesUnifiedOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmail = scenario.MatchScenario.matchesEstatement ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmail = scenario.MatchScenario.matchesENotification ? email.RandomizeCase() : unmatchedEmail
|
||||
};
|
||||
|
||||
var updated = await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
Assert.IsTrue(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailSucceededToSend_NullEmailMatched_ReturnsTrue(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = scenario.MatchScenario.matchesUnifiedOptin ? null : unmatchedEmail,
|
||||
EStatementsEmail = scenario.MatchScenario.matchesEstatement ? null : unmatchedEmail,
|
||||
ENotificationsEmail = scenario.MatchScenario.matchesENotification ? null : unmatchedEmail
|
||||
};
|
||||
|
||||
var updated = await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
Assert.IsTrue(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailSucceededToSend_EmailMatchesRegardlessOfCase_UpdatesTrackingOnMatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = matchesUnifiedOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
var actionStart = DateTime.Now;
|
||||
|
||||
await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
var elapsedActionTime = DateTime.Now - actionStart;
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
if (matchesUnifiedOptin)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.UnifiedOptInEmailFirstSent);
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesEstatement)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.EStatementsEmailFirstSent);
|
||||
Assert.That(updatedSettings.EStatementsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesENotification)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.ENotificationsEmailFirstSent);
|
||||
Assert.That(updatedSettings.ENotificationsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailSucceededToSend_NullEmailMatched_UpdatesTrackingOnMatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = matchesUnifiedOptin ? null : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement ? null : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification ? null : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
var actionStart = DateTime.Now;
|
||||
|
||||
await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
var elapsedActionTime = DateTime.Now - actionStart;
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
if (matchesUnifiedOptin)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.UnifiedOptInEmailFirstSent);
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesEstatement)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.EStatementsEmailFirstSent);
|
||||
Assert.That(updatedSettings.EStatementsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesENotification)
|
||||
{
|
||||
Assert.IsNull(updatedSettings.ENotificationsEmailFirstSent);
|
||||
Assert.That(updatedSettings.ENotificationsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.DeliveredSuccessfully, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(0, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailSucceededToSend_EmailMatchesRegardlessOfCase_DoesNotUpdateTrackingOnUnmatched(
|
||||
UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = matchesUnifiedOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
|
||||
await _service.EmailSucceededToSend(userId, email);
|
||||
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
if (!matchesUnifiedOptin)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.UnifiedOptInEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesEstatement)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.EStatementsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesENotification)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.ENotificationsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_UserOptInSettingsNotFound_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings.Remove(userId);
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, EmailAddressFactory(), true);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_EmailMatchesNoOptinEmailPreference_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = EmailAddressFactory(),
|
||||
EStatementsEmail = EmailAddressFactory(),
|
||||
ENotificationsEmail = EmailAddressFactory()
|
||||
};
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_NullEmailMatchesNoOptinEmailPreference_ReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = EmailAddressFactory(),
|
||||
EStatementsEmail = EmailAddressFactory(),
|
||||
ENotificationsEmail = EmailAddressFactory()
|
||||
};
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_EmailMatchesRegardlessOfCase_ReturnsTrue(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UniversalOptIn = isUniversalOptin ? "Electronic" : null,
|
||||
UnifiedOptInEmail = matchesUnifiedOptin && isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = isUniversalOptin ? DateTime.Now : firstSent,
|
||||
UnifiedOptInEmailLastSent = isUniversalOptin ? DateTime.Now : lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
Assert.IsTrue(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_NullEmailMatched_ReturnsTrue(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UniversalOptIn = isUniversalOptin ? "Electronic" : null,
|
||||
UnifiedOptInEmail = matchesUnifiedOptin && isUniversalOptin ? null : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement && !isUniversalOptin ? null : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification && !isUniversalOptin ? null : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
Assert.IsTrue(updated);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_EmailMatchesRegardlessOfCase_UpdatesTrackingOnMatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UniversalOptIn = isUniversalOptin ? "Electronic" : null,
|
||||
UnifiedOptInEmail = matchesUnifiedOptin && isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
var actionStart = DateTime.Now;
|
||||
|
||||
await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
var elapsedActionTime = DateTime.Now - actionStart;
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
var updatedFirstSent = firstSent is null
|
||||
? Is.EqualTo(actionStart).Within(elapsedActionTime)
|
||||
: Is.EqualTo(firstSent);
|
||||
if (matchesUnifiedOptin && isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesEstatement && !isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.EStatementsEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.EStatementsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesENotification && !isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.ENotificationsEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.ENotificationsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_NullEmailMatched_UpdatesTrackingOnMatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UniversalOptIn = isUniversalOptin ? "Electronic" : null,
|
||||
UnifiedOptInEmail = matchesUnifiedOptin && isUniversalOptin ? null : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement && !isUniversalOptin ? null : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification && !isUniversalOptin ? null : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
var actionStart = DateTime.Now;
|
||||
|
||||
await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
var elapsedActionTime = DateTime.Now - actionStart;
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
var updatedFirstSent = firstSent is null
|
||||
? Is.EqualTo(actionStart).Within(elapsedActionTime)
|
||||
: Is.EqualTo(firstSent);
|
||||
if (matchesUnifiedOptin && isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.UnifiedOptInEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesEstatement && !isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.EStatementsEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.EStatementsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (matchesENotification && !isUniversalOptin)
|
||||
{
|
||||
Assert.That(updatedSettings.ENotificationsEmailFirstSent, updatedFirstSent);
|
||||
Assert.That(updatedSettings.ENotificationsEmailLastSent,
|
||||
Is.EqualTo(actionStart).Within(elapsedActionTime));
|
||||
Assert.AreEqual(EmailStatus.FailingDelivery, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(count + 1, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_EmailMatchesRegardlessOfCase_DoesNotUpdateTrackingOnUnmatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
var email = EmailAddressFactory();
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = matchesUnifiedOptin && isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification && !isUniversalOptin ? email.RandomizeCase() : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
|
||||
await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
if (!matchesUnifiedOptin)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.UnifiedOptInEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesEstatement)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.EStatementsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesENotification)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.ENotificationsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(UpdateScenarios))]
|
||||
public async Task EmailFailedToSend_NullEmailMatched_DoesNotUpdateTrackingOnUnmatched(UpdateScenario scenario)
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
string email = null;
|
||||
var unmatchedEmail = EmailAddressFactory();
|
||||
var (isUniversalOptin, matchesUnifiedOptin, matchesEstatement, matchesENotification) = scenario.MatchScenario;
|
||||
var (firstSent, lastSent, status, count) = scenario.PriorState;
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings
|
||||
{
|
||||
UnifiedOptInEmail = matchesUnifiedOptin ? null : unmatchedEmail,
|
||||
UnifiedOptInEmailFirstSent = firstSent,
|
||||
UnifiedOptInEmailLastSent = lastSent,
|
||||
UnifiedOptInEmailStatus = status,
|
||||
UnifiedOptInEmailStatusCount = count,
|
||||
EStatementsEmail = matchesEstatement ? null : unmatchedEmail,
|
||||
EStatementsEmailFirstSent = firstSent,
|
||||
EStatementsEmailLastSent = lastSent,
|
||||
EStatementsEmailStatus = status,
|
||||
EStatementsEmailStatusCount = count,
|
||||
ENotificationsEmail = matchesENotification ? null : unmatchedEmail,
|
||||
ENotificationsEmailFirstSent = firstSent,
|
||||
ENotificationsEmailLastSent = lastSent,
|
||||
ENotificationsEmailStatus = status,
|
||||
ENotificationsEmailStatusCount = count
|
||||
};
|
||||
|
||||
await _service.EmailFailedToSend(userId, email, true);
|
||||
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
if (!matchesUnifiedOptin)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.UnifiedOptInEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.UnifiedOptInEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.UnifiedOptInEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.UnifiedOptInEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesEstatement)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.EStatementsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.EStatementsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.EStatementsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.EStatementsEmailStatusCount);
|
||||
}
|
||||
|
||||
if (!matchesENotification)
|
||||
{
|
||||
Assert.AreEqual(firstSent, updatedSettings.ENotificationsEmailFirstSent);
|
||||
Assert.AreEqual(lastSent, updatedSettings.ENotificationsEmailLastSent);
|
||||
Assert.AreEqual(status, updatedSettings.ENotificationsEmailStatus);
|
||||
Assert.AreEqual(count, updatedSettings.ENotificationsEmailStatusCount);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_PolicyMakesUpdate_ReturnsTrue()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings { UserId = userId, EStatementsEmail = "" };
|
||||
_policies[1]
|
||||
.Setup(p => p.Apply(It.Is<MemberOptInSettings>(s => s.UserId == userId), It.IsAny<bool>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, string.Empty, true);
|
||||
|
||||
Assert.IsTrue(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_PolicyMakesUpdate_FeatureFlagReturnsFalse()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings { UserId = userId };
|
||||
_policies[1]
|
||||
.Setup(p => p.Apply(It.Is<MemberOptInSettings>(s => s.UserId == userId), It.IsAny<bool>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
var updated = await _service.EmailFailedToSend(userId, string.Empty, false);
|
||||
|
||||
Assert.IsFalse(updated);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_PolicyMakesUpdate_UpdatesTracking()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings { UserId = userId };
|
||||
_policies[1]
|
||||
.Setup(p => p.Apply(It.Is<MemberOptInSettings>(s => s.UserId == userId), It.IsAny<bool>()))
|
||||
.Callback<MemberOptInSettings, bool>((s, b) => s.LastUpdatedBy = nameof(EmailFailedToSend_PolicyMakesUpdate_UpdatesTracking))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
await _service.EmailFailedToSend(userId, string.Empty, true);
|
||||
|
||||
var updatedSettings = _repository.MemberOptInSettings[userId];
|
||||
Assert.AreEqual(nameof(EmailFailedToSend_PolicyMakesUpdate_UpdatesTracking), updatedSettings.LastUpdatedBy);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmailFailedToSend_AllCases_EvaluatesAllFailurePolicies()
|
||||
{
|
||||
var userId = Guid.NewGuid().ToString();
|
||||
_repository.MemberOptInSettings[userId] = new MemberOptInSettings { UserId = userId };
|
||||
_policies[1]
|
||||
.Setup(p => p.Apply(It.Is<MemberOptInSettings>(s => s.UserId == userId), It.IsAny<bool>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
await _service.EmailFailedToSend(userId, string.Empty, true);
|
||||
|
||||
foreach (var policy in _policies)
|
||||
{
|
||||
policy.Verify(p => p.Apply(It.Is<MemberOptInSettings>(s => s.UserId == userId), It.IsAny<bool>()));
|
||||
}
|
||||
}
|
||||
|
||||
private interface IObservableRepository<in TKey, in TValue>
|
||||
{
|
||||
void ApplyChanges(TKey key, TValue value);
|
||||
}
|
||||
|
||||
private class FakeUnifiedOptInRepository : IUnifiedOptInRepository,
|
||||
IObservableRepository<string, MemberOptInSettings>
|
||||
{
|
||||
public IDictionary<string, MemberOptInSettings> MemberOptInSettings { get; } =
|
||||
new Dictionary<string, MemberOptInSettings>();
|
||||
|
||||
private readonly IRepositoryObserver<string, MemberOptInSettings> _observer;
|
||||
|
||||
public FakeUnifiedOptInRepository(IRepositoryObserver<string, MemberOptInSettings> observer)
|
||||
{
|
||||
_observer = observer;
|
||||
_observer.Observe(this);
|
||||
}
|
||||
|
||||
public Task<MemberOptInSettings> GetMemberOptInSettings(string userId)
|
||||
{
|
||||
if (!MemberOptInSettings.TryGetValue(userId, out var optInSettings))
|
||||
{
|
||||
return Task.FromResult<MemberOptInSettings>(null);
|
||||
}
|
||||
|
||||
var clonedSettings = JsonConvert.DeserializeObject<MemberOptInSettings>
|
||||
(
|
||||
JsonConvert.SerializeObject(optInSettings)
|
||||
);
|
||||
_observer.Track(userId, clonedSettings);
|
||||
|
||||
return Task.FromResult(clonedSettings);
|
||||
}
|
||||
|
||||
public Task<MemberOptInSettings> GetMemberOptInSettingsNoTracking(string userId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<MemberOptInSettings> GetOrCreateMemberOptinSettings(string userId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<List<MemberOptInSettings>> GetAllMemberOptInSettings(List<string> memberNumbers)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ApplyChanges(string key, MemberOptInSettings value)
|
||||
{
|
||||
MemberOptInSettings[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private interface IRepositoryObserver<TKey, TValue>
|
||||
{
|
||||
void Track(TKey key, TValue value);
|
||||
void Observe(IObservableRepository<TKey, TValue> subject);
|
||||
}
|
||||
|
||||
private class FakeUnitOfWork : IUnitOfWork, IRepositoryObserver<string, MemberOptInSettings>
|
||||
{
|
||||
private readonly IDictionary<string, MemberOptInSettings> _activeRecords =
|
||||
new Dictionary<string, MemberOptInSettings>();
|
||||
|
||||
private IObservableRepository<string, MemberOptInSettings> _subject;
|
||||
|
||||
public Task CompleteAsync()
|
||||
{
|
||||
foreach (var record in _activeRecords)
|
||||
{
|
||||
_subject.ApplyChanges(record.Key, record.Value);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task CompleteAsync(string operatorId, DateTime dateAdded, UserType userType)
|
||||
{
|
||||
return CompleteAsync();
|
||||
}
|
||||
|
||||
public void Track(string key, MemberOptInSettings value)
|
||||
{
|
||||
_activeRecords[key] = value;
|
||||
}
|
||||
|
||||
public void Observe(IObservableRepository<string, MemberOptInSettings> subject)
|
||||
{
|
||||
_subject = subject;
|
||||
}
|
||||
}
|
||||
|
||||
public struct UpdateScenario
|
||||
{
|
||||
public (DateTime? firstSent, DateTime? lastSent, EmailStatus status, int count) PriorState { get; }
|
||||
public (bool isUniversalOptIn, bool matchesUnifiedOptin, bool matchesENotification, bool matchesEstatement) MatchScenario { get; }
|
||||
|
||||
public UpdateScenario((DateTime? firstSent, DateTime? lastSent, EmailStatus status, int count) priorState,
|
||||
(bool isUniveralsOptin, bool matchesUnifiedOptin, bool matchesENotification, bool matchesEstatement) matchScenario)
|
||||
{
|
||||
PriorState = priorState;
|
||||
MatchScenario = matchScenario;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RandomCaseExtension
|
||||
{
|
||||
private static readonly Random Random = new Random(DateTime.Now.Millisecond);
|
||||
public static string RandomizeCase(this string s)
|
||||
{
|
||||
static char RandomCase(char c) => Random.Next() % 2 == 0 ? char.ToUpper(c) : char.ToLower(c);
|
||||
|
||||
return string.Concat(s.Select(RandomCase));
|
||||
}
|
||||
}
|
||||
+895
@@ -0,0 +1,895 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Infrastructure.Services;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Requests;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Persistence;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class MemberPreferenceServiceTest
|
||||
{
|
||||
private MemberPreferenceService _memberPreferenceService;
|
||||
private IMemberPreferenceRepository _memberPreferenceRepository;
|
||||
private IUnifiedOptInRepository _unifiedOptInRepository;
|
||||
private Mock<INotificationService> _mockNotificationService;
|
||||
private Mock<IIntegrationService> _mockIntegrationService;
|
||||
private Mock<IXdiBatchService> _xdiBatchItemServiceMock;
|
||||
private Mock<ICoreApiWrapperService> _mockCoreApiWrapperService;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var mockDateTime = new DateTimeService();
|
||||
_mockNotificationService = new Mock<INotificationService>();
|
||||
_mockIntegrationService = new Mock<IIntegrationService>();
|
||||
_xdiBatchItemServiceMock = new Mock<IXdiBatchService>();
|
||||
_mockCoreApiWrapperService = new Mock<ICoreApiWrapperService>();
|
||||
|
||||
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.EnableSensitiveDataLogging()
|
||||
.Options;
|
||||
var context = new ApplicationDbContext(options);
|
||||
_memberPreferenceRepository = new MemberPreferenceRepository(context);
|
||||
_unifiedOptInRepository = new UnifiedOptInRepository(context);
|
||||
_memberPreferenceService = new MemberPreferenceService(_memberPreferenceRepository, new UnitOfWork(context),
|
||||
_unifiedOptInRepository, _mockNotificationService.Object, _mockIntegrationService.Object,
|
||||
_xdiBatchItemServiceMock.Object, _mockCoreApiWrapperService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Basic_Flow()
|
||||
{
|
||||
var saved = await _memberPreferenceService.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsEmpty(saved);
|
||||
|
||||
var preference = new MemberPreferenceRequest
|
||||
{
|
||||
UserId = "99",
|
||||
Preference = PreferenceType.ENotification,
|
||||
Value = "True"
|
||||
};
|
||||
var result = await _memberPreferenceService.SaveMemberPreferenceAsync(preference);
|
||||
Assert.NotNull(result);
|
||||
|
||||
saved = await _memberPreferenceService.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnifiedOptIn_Flow()
|
||||
{
|
||||
var saved = await _memberPreferenceService.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsEmpty(saved);
|
||||
|
||||
_mockNotificationService
|
||||
.Setup(x => x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()));
|
||||
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var preference = new MemberOptinRequest
|
||||
{
|
||||
UserId = "99",
|
||||
Email = "[email protected]",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
LegalReference = "1.0.0"
|
||||
};
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(preference);
|
||||
|
||||
saved = await _memberPreferenceService.GetMemberPreferencesAsync("99");
|
||||
Assert.NotNull(saved);
|
||||
Assert.IsNotEmpty(saved);
|
||||
_mockIntegrationService.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateMemberOptInAsync_Email_Ok()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>())).Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest
|
||||
{
|
||||
Email = "[email protected]",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateMemberOptInAsync_Paper_Ok()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var agreement = new Agreement
|
||||
{
|
||||
UserId = "12",
|
||||
ByOrgNbr = 0,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
};
|
||||
|
||||
var accounts = new List<AgreementAccount>
|
||||
{
|
||||
new AgreementAccount
|
||||
{
|
||||
AccountNumber = 123,
|
||||
TaxReportForPersonNumber = 111,
|
||||
OvrDeliveryMethCD = "WWW",
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementByUserId("12")).ReturnsAsync(agreement).Verifiable();
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementAccountsByUserId("12")).ReturnsAsync(accounts)
|
||||
.Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest
|
||||
{
|
||||
Value = DeliveryPreference.Paper,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Once);
|
||||
_mockCoreApiWrapperService.Verify();
|
||||
_mockCoreApiWrapperService.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(l => l.Contains(123)), It.Is<string>(d => d.Equals("PRNT")), It.Is<string>(u => u.Equals("12"))), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateMemberOptInAsync_Electronic_Ok()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var agreement = new Agreement
|
||||
{
|
||||
UserId = "12",
|
||||
ByOrgNbr = 0,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
};
|
||||
|
||||
var accounts = new List<AgreementAccount>
|
||||
{
|
||||
new AgreementAccount
|
||||
{
|
||||
AccountNumber = 123,
|
||||
TaxReportForPersonNumber = 111,
|
||||
OvrDeliveryMethCD = "PRNT",
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementByUserId("12")).ReturnsAsync(agreement).Verifiable();
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementAccountsByUserId("12")).ReturnsAsync(accounts).Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest
|
||||
{
|
||||
Email = "[email protected]",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Once);
|
||||
_mockCoreApiWrapperService.Verify();
|
||||
_mockCoreApiWrapperService.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(l => l.Contains(123)), It.Is<string>(d => d.Equals("WWW")), It.Is<string>(u => u.Equals("12"))), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateMemberOptInAsync_Organization_Electronic_Ok()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>())).Verifiable();
|
||||
|
||||
var agreement = new Agreement
|
||||
{
|
||||
UserId = "12",
|
||||
PersonNumber = 111,
|
||||
ByOrgNbr = 112,
|
||||
AgreementNumber = 54321
|
||||
};
|
||||
|
||||
var organizationAccounts = new List<AgreementAccount>
|
||||
{
|
||||
new AgreementAccount
|
||||
{
|
||||
AccountNumber = 123,
|
||||
TaxReportForOrgNumber = 112,
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 123,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
}
|
||||
},
|
||||
new AgreementAccount
|
||||
{
|
||||
AccountNumber = 124,
|
||||
TaxReportForOrgNumber = 112,
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 124,
|
||||
PersonNumber = 115,
|
||||
AgreementNumber = 5432
|
||||
}
|
||||
},
|
||||
new AgreementAccount
|
||||
{
|
||||
AccountNumber = 125,
|
||||
TaxReportForOrgNumber = 112,
|
||||
AccountOwner = new AgreementAccountOwner
|
||||
{
|
||||
AccountNumber = 125,
|
||||
PersonNumber = 111,
|
||||
AgreementNumber = 54321
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementByUserId("12")).ReturnsAsync(agreement).Verifiable();
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementAccountsByOrganizationId(112)).ReturnsAsync(organizationAccounts).Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest
|
||||
{
|
||||
Email = "[email protected]",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Once);
|
||||
_mockCoreApiWrapperService.Verify();
|
||||
_mockCoreApiWrapperService.Verify(x => x.UpdateAgreementAccountsDeliveryMethod(It.Is<List<long>>(l => l.Contains(123) && l.Contains(125)), It.Is<string>(d => d.Equals("WWW")), It.Is<string>(u => u.Equals("12"))), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateMemberOptInAsync_Email_RequiresValidEmail()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest
|
||||
{
|
||||
Email = "gmail",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
Assert.ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
});
|
||||
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateMemberOptInAsync_Email_RequiresEmail()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
Assert.ThrowsAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
});
|
||||
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdateMemberOptInAsync_DoesNothing_If_Invalid_Value_Ok()
|
||||
{
|
||||
_mockIntegrationService.Setup(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()))
|
||||
.Verifiable();
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
Email = "[email protected]",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
UserId = "12",
|
||||
LegalReference = ""
|
||||
};
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request);
|
||||
_mockIntegrationService.Verify(x => x.NotifyListeners(It.IsAny<MemberOptInSettings>()), Times.Once);
|
||||
}
|
||||
|
||||
[TestCase(PreferenceType.EStatements, "Paper", false)]
|
||||
[TestCase(PreferenceType.EStatements, "Email", true)]
|
||||
[TestCase(PreferenceType.EStatementsEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.EStatements, "[email protected]", true)]
|
||||
[TestCase(PreferenceType.ENotificationsEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.ENotification, "[email protected]", true)]
|
||||
[TestCase(PreferenceType.UnifiedOptInEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.UnifiedOptIn, "Electronic", false)]
|
||||
public void IsExternalUpdateNecessary_NoUnified_OK(PreferenceType pref, string requestValue, bool assertion)
|
||||
{
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
ENotifications = "Paper",
|
||||
EStatements = "Paper",
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
};
|
||||
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = pref,
|
||||
Value = requestValue
|
||||
};
|
||||
|
||||
Assert.AreEqual(assertion, _memberPreferenceService.IsExternalUpdateNecessary(settings, request));
|
||||
}
|
||||
|
||||
[TestCase(PreferenceType.EStatements, "Paper", false)]
|
||||
[TestCase(PreferenceType.EStatements, "Email", true)]
|
||||
[TestCase(PreferenceType.EStatementsEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.EStatements, "[email protected]", true)]
|
||||
[TestCase(PreferenceType.ENotificationsEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.ENotification, "[email protected]", true)]
|
||||
[TestCase(PreferenceType.UnifiedOptInEmail, "[email protected]", false)]
|
||||
[TestCase(PreferenceType.UnifiedOptInEmail, "[email protected]", true)]
|
||||
[TestCase(PreferenceType.UnifiedOptIn, "Electronic", true)]
|
||||
[TestCase(PreferenceType.UnifiedOptIn, "Paper", false)]
|
||||
public void IsExternalUpdateNecessary_HasUnified_OK(PreferenceType pref, string requestValue, bool assertion)
|
||||
{
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
ENotifications = "Paper",
|
||||
EStatements = "Paper",
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = "Paper"
|
||||
};
|
||||
|
||||
var request = new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = pref,
|
||||
Value = requestValue
|
||||
};
|
||||
|
||||
Assert.AreEqual(assertion, _memberPreferenceService.IsExternalUpdateNecessary(settings, request));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SaveMemberPreferencesDefault_OK()
|
||||
{
|
||||
var paperDefault =
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = "Paper",
|
||||
LegalReference = "test",
|
||||
};
|
||||
|
||||
var result =
|
||||
await _memberPreferenceService.SaveMemberPreferenceDefaultAsync(paperDefault, "1337",
|
||||
UserType.Associate,
|
||||
DateTime.Parse("2021-02-12"));
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.AreEqual("1337", result.LastUpdatedBy);
|
||||
Assert.AreEqual(DateTime.Parse("2021-02-12"), result.LastUpdated);
|
||||
Assert.AreEqual(UserType.Associate, result.LastUpdatedByType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SaveMemberPreferences_Null_ThrowsArgumentException()
|
||||
{
|
||||
Assert.ThrowsAsync<ArgumentException>(async () =>
|
||||
await _memberPreferenceService.SaveMemberPreferencesAsync(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SaveMemberPreferences_Empty_ThrowsArgumentException()
|
||||
{
|
||||
Assert.ThrowsAsync<ArgumentException>(async () =>
|
||||
await _memberPreferenceService.SaveMemberPreferencesAsync(new List<MemberPreferenceRequest>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SaveMemberPreferences_HasPendingXdiUpdate_PendingUpdatesException()
|
||||
{
|
||||
var preference = new List<MemberPreferenceRequest>
|
||||
{
|
||||
new MemberPreferenceRequest
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = "Paper",
|
||||
UserId = "222"
|
||||
}
|
||||
};
|
||||
|
||||
_xdiBatchItemServiceMock.Setup(x => x.DoesMemberHavePendingXdiChange("222")).ReturnsAsync(true).Verifiable();
|
||||
|
||||
Assert.ThrowsAsync<Exception>(async () => await _memberPreferenceService.SaveMemberPreferencesAsync(preference));
|
||||
_xdiBatchItemServiceMock.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SaveMemberPreferencesDefault_NoChange_OK()
|
||||
{
|
||||
await _memberPreferenceService.SaveMemberPreferencesAsync(new List<MemberPreferenceRequest>()
|
||||
{
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = "Electronic",
|
||||
LegalReference = "test",
|
||||
},
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.EStatements,
|
||||
Value = "Electronic",
|
||||
LegalReference = "test",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
var emailRequests =
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = "Electronic",
|
||||
LegalReference = "test",
|
||||
};
|
||||
|
||||
var result =
|
||||
await _memberPreferenceService.SaveMemberPreferenceDefaultAsync(emailRequests, "1337", UserType.System,
|
||||
DateTime.Parse("2021-02-12"));
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.AreEqual("Electronic", result.UniversalOptIn);
|
||||
Assert.AreEqual("Electronic", result.EStatements);
|
||||
Assert.AreNotEqual(DateTime.Parse("2021-02-12"), result.LastUpdatedBy);
|
||||
Assert.AreNotEqual("1337", result.LastUpdated);
|
||||
Assert.AreEqual(UserType.System, result.LastUpdatedByType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateMemberOptInAsync_BadEmail()
|
||||
{
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "234@",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
Assert.ThrowsAsync<FormatException>(async () =>
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request));
|
||||
|
||||
request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
Assert.ThrowsAsync<ArgumentNullException>(async () =>
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(request));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Unknown_To_Paper()
|
||||
{
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper,
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, null);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Unknown_To_Paper_IgnoresRequestEmail()
|
||||
{
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, null);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Email_To_Paper()
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = "[email protected]",
|
||||
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = DeliveryPreference.Electronic
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper,
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.Is<List<string>>(emails => emails.Count == 1)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Email_To_Paper_IgnoreRequestEmail()
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = "[email protected]",
|
||||
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = DeliveryPreference.Electronic
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.Is<List<string>>(emails => emails.Count == 1)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Paper_To_Email()
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = "[email protected]",
|
||||
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = DeliveryPreference.Paper
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.Is<List<string>>(emails => emails.Count == 1),
|
||||
It.IsAny<MemberOptinRequest>()));
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Unknown_To_Email()
|
||||
{
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, null);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.Is<List<string>>(emails => emails.Count == 1),
|
||||
It.IsAny<MemberOptinRequest>()));
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Email_To_Email_NoChange()
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = "[email protected]",
|
||||
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = DeliveryPreference.Electronic
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SendOptInChangeNotification_Email_To_Email_IsChange()
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = "[email protected]",
|
||||
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
UniversalOptIn = DeliveryPreference.Electronic
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendEmailChangeNotifications(It.Is<List<string>>(emails => emails.Count == 2),
|
||||
It.IsAny<MemberOptinRequest>()));
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestCase("[email protected]", "[email protected]", 3)]
|
||||
[TestCase("[email protected]", "[email protected]", 3)]
|
||||
[TestCase("[email protected]", "[email protected]", 3)]
|
||||
[TestCase("[email protected]", "[email protected]", 3)]
|
||||
[TestCase(null, "[email protected]", 2)]
|
||||
[TestCase("[email protected]", null, 2)]
|
||||
public async Task SendOptInChangeNotification_Historic_To_Email(string eStatementsEmail,
|
||||
string eNotificationsEmail, int optInEmailCount)
|
||||
{
|
||||
var existing = new MemberOptInSettings()
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = eStatementsEmail,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = eNotificationsEmail
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Electronic,
|
||||
Email = "[email protected]",
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.Is<List<string>>(emails => emails.Count == optInEmailCount),
|
||||
It.IsAny<MemberOptinRequest>()));
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestCase("[email protected]", "[email protected]", 2)]
|
||||
[TestCase("[email protected]", "[email protected]", 2)]
|
||||
[TestCase("[email protected]", "[email protected]", 2)]
|
||||
[TestCase("[email protected]", "[email protected]", 2)]
|
||||
[TestCase(null, "[email protected]", 1)]
|
||||
[TestCase("[email protected]", null, 1)]
|
||||
public async Task SendOptInChangeNotification_Historic_To_Paper(string eStatementsEmail,
|
||||
string eNotificationsEmail, int optOutEmailCount)
|
||||
{
|
||||
var existing = new MemberOptInSettings
|
||||
{
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
EStatementsEmail = eStatementsEmail,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
ENotificationsEmail = eNotificationsEmail
|
||||
};
|
||||
|
||||
var request = new MemberOptinRequest()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper,
|
||||
LegalReference = "none"
|
||||
};
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>())).Verifiable();
|
||||
|
||||
_mockNotificationService.Setup(x =>
|
||||
x.SendOptOutNotifications(It.IsAny<List<string>>())).Verifiable();
|
||||
|
||||
await _memberPreferenceService.SendOptInChangeNotifications(request, existing);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptInNotifications(It.IsAny<List<string>>(), It.IsAny<MemberOptinRequest>()), Times.Never);
|
||||
|
||||
_mockNotificationService.Verify(x =>
|
||||
x.SendOptOutNotifications(It.Is<List<string>>(emails => emails.Count == optOutEmailCount)));
|
||||
}
|
||||
|
||||
[TestCase(DeliveryPreference.Paper, "[email protected]", DeliveryPreference.Electronic,
|
||||
"[email protected]", 1)]
|
||||
[TestCase(DeliveryPreference.Electronic, "[email protected]", DeliveryPreference.Paper,
|
||||
"[email protected]", 1)]
|
||||
[TestCase(DeliveryPreference.Electronic, "[email protected]", DeliveryPreference.Electronic,
|
||||
"[email protected]", 2)]
|
||||
[TestCase(DeliveryPreference.Electronic, "", DeliveryPreference.Electronic, "[email protected]", 1)]
|
||||
[TestCase(DeliveryPreference.Electronic, "[email protected]", DeliveryPreference.Electronic, null, 1)]
|
||||
[TestCase(DeliveryPreference.Paper, "[email protected]", DeliveryPreference.Paper,
|
||||
"[email protected]", 0)]
|
||||
public void TryAddHistoricEmails_Ok(string eNotificationsValue, string eNotificationsEmail,
|
||||
string eStatementsValue, string eStatementsEmail, int assertCount)
|
||||
{
|
||||
var ogSettings = new MemberOptInSettings()
|
||||
{
|
||||
ENotifications = eNotificationsValue,
|
||||
ENotificationsEmail = eNotificationsEmail,
|
||||
EStatements = eStatementsValue,
|
||||
EStatementsEmail = eStatementsEmail
|
||||
};
|
||||
|
||||
var affectedEmails = new List<string>();
|
||||
|
||||
_memberPreferenceService.TryAddHistoricEmails(ogSettings, affectedEmails);
|
||||
|
||||
Assert.AreEqual(assertCount, affectedEmails.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class UnifiedOptInServiceTest
|
||||
{
|
||||
private OptinService _service;
|
||||
private Mock<IUnifiedOptInRepository> _mockRepository;
|
||||
private Mock<IXdiBatchService> _mockXdiBatchItemService;
|
||||
private Mock<ICoreApiWrapperService> _mockCoreApiWrapperService;
|
||||
private Mock<IMemberPreferenceService> _mockMemberPreferenceService;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mockRepository = new Mock<IUnifiedOptInRepository>();
|
||||
_mockXdiBatchItemService = new Mock<IXdiBatchService>();
|
||||
_mockCoreApiWrapperService = new Mock<ICoreApiWrapperService>();
|
||||
_mockMemberPreferenceService = new Mock<IMemberPreferenceService>();
|
||||
_service = new OptinService(_mockRepository.Object, _mockXdiBatchItemService.Object, _mockMemberPreferenceService.Object, _mockCoreApiWrapperService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Get_OptIn_OK()
|
||||
{
|
||||
var testSettings1 = new MemberOptInSettings
|
||||
{
|
||||
UserId = "1",
|
||||
UniversalOptIn = "Email"
|
||||
};
|
||||
|
||||
_mockRepository.Setup(x => x.GetMemberOptInSettings("1")).ReturnsAsync(testSettings1).Verifiable();
|
||||
// act
|
||||
var result = await _service.GetMemberOptInSettings("1");
|
||||
Assert.NotNull(result);
|
||||
Assert.AreEqual("1", result.UserId);
|
||||
Assert.AreEqual("Email", result.UniversalOptIn);
|
||||
_mockRepository.Verify();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetMemberOptInAgreementInformation_OptIn_OK()
|
||||
{
|
||||
|
||||
var agreements = new List<Agreement>
|
||||
{
|
||||
new Agreement
|
||||
{
|
||||
UserId = "1"
|
||||
},
|
||||
new Agreement
|
||||
{
|
||||
UserId = "2"
|
||||
}
|
||||
};
|
||||
|
||||
var testSetting = new MemberOptInSettings
|
||||
{
|
||||
UserId = "1",
|
||||
UniversalOptIn = "Email"
|
||||
};
|
||||
|
||||
_mockCoreApiWrapperService.Setup(x => x.GetAgreementsByAccountId(123)).ReturnsAsync(agreements).Verifiable();
|
||||
_mockRepository.Setup(x => x.GetMemberOptInSettings("1")).ReturnsAsync(testSetting).Verifiable();
|
||||
_mockRepository.Setup(x => x.GetMemberOptInSettings("2")).ReturnsAsync(testSetting).Verifiable();
|
||||
|
||||
// act
|
||||
var result = await _service.GetMemberOptInAgreementInformationByAccountId(123);
|
||||
Assert.NotNull(result);
|
||||
Assert.IsNotEmpty(result);
|
||||
_mockCoreApiWrapperService.Verify();
|
||||
_mockRepository.Verify();
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task TransformMemberOptInSettingsForClient_OK(bool hasPending)
|
||||
{
|
||||
var testSettings1 = new MemberOptInSettings
|
||||
{
|
||||
Id = 10,
|
||||
UserId = "100",
|
||||
EStatements = DeliveryPreference.Microfiche,
|
||||
ENotifications = DeliveryPreference.Paper,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
LegalVersion = "2021/01/01",
|
||||
LegalDate = DateTime.Parse("2021/01/01"),
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
Created = DateTime.Parse("2021/01/01"),
|
||||
CreatedBy = "TestUser",
|
||||
CreatedByType = UserType.Associate,
|
||||
LastUpdated = DateTime.Parse("2021/02/01"),
|
||||
LastUpdatedBy = "TestMember",
|
||||
LastUpdatedByType = UserType.Member,
|
||||
};
|
||||
|
||||
_mockXdiBatchItemService.Setup(x => x.DoesMemberHavePendingXdiChange(It.IsAny<string>()))
|
||||
.ReturnsAsync(hasPending);
|
||||
// act
|
||||
var transformation = await _service.TransformMemberOptInSettingsForClient(testSettings1);
|
||||
Assert.NotNull(transformation);
|
||||
var result = transformation.MemberOptinSettings;
|
||||
Assert.AreEqual(10, result.Id);
|
||||
Assert.AreEqual("100", result.UserId);
|
||||
Assert.AreEqual(DeliveryPreference.Microfiche, result.EStatements);
|
||||
Assert.AreEqual(DeliveryPreference.Paper, result.ENotifications);
|
||||
Assert.AreEqual(DeliveryPreference.Electronic, result.UniversalOptIn);
|
||||
Assert.AreEqual("2021/01/01", result.LegalVersion);
|
||||
Assert.AreEqual(DateTime.Parse("2021/01/01"), result.LegalDate);
|
||||
Assert.AreEqual("[email protected]", result.UnifiedOptInEmail);
|
||||
Assert.AreEqual("[email protected]", result.EStatementsEmail);
|
||||
Assert.AreEqual("[email protected]", result.ENotificationsEmail);
|
||||
Assert.AreEqual(DateTime.Parse("2021/01/01"), result.Created);
|
||||
Assert.AreEqual("TestUser", result.CreatedBy);
|
||||
Assert.AreEqual(UserType.Associate, result.CreatedByType);
|
||||
Assert.AreEqual(DateTime.Parse("2021/02/01"), result.LastUpdated);
|
||||
Assert.AreEqual("TestMember", result.LastUpdatedBy);
|
||||
Assert.AreEqual(UserType.Member, result.LastUpdatedByType);
|
||||
Assert.AreEqual(hasPending, transformation.HasPendingUpdates);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TransformMemberOptInSettingsForClient_List_OK()
|
||||
{
|
||||
var testSettings1 = new List<MemberOptInSettings>
|
||||
{
|
||||
new MemberOptInSettings
|
||||
{
|
||||
UserId = "9",
|
||||
UniversalOptIn = "Email"
|
||||
},
|
||||
new MemberOptInSettings
|
||||
{
|
||||
UserId = "10",
|
||||
UniversalOptIn = "Paper"
|
||||
},
|
||||
};
|
||||
_mockXdiBatchItemService.Setup(x => x.DoesMemberHavePendingXdiChange("9"))
|
||||
.ReturnsAsync(true).Verifiable();
|
||||
_mockXdiBatchItemService.Setup(x => x.DoesMemberHavePendingXdiChange("10"))
|
||||
.ReturnsAsync(false).Verifiable();
|
||||
// act
|
||||
var result = await _service.TransformMemberOptInSettingsForClient(testSettings1);
|
||||
_mockXdiBatchItemService.Verify();
|
||||
Assert.NotNull(result);
|
||||
Assert.IsNotEmpty(result);
|
||||
Assert.AreEqual(result.Count, 2);
|
||||
Assert.True(result.ToList().Exists(x => x.HasPendingUpdates));
|
||||
Assert.True(result.ToList().Exists(x => !x.HasPendingUpdates));
|
||||
}
|
||||
}
|
||||
}
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.Services
|
||||
{
|
||||
public class XdiBatchItemServiceTest
|
||||
{
|
||||
private IXdiBatchService _xdiBatchItemService;
|
||||
private Mock<IXdiBatchItemsRepository> _mockBatchItemsRepository;
|
||||
private Mock<IUnitOfWork> _mockUnitOfWork;
|
||||
private XdiSftpApiConfiguration _ftpConfiguration;
|
||||
private Mock<IUnifiedOptInRepository> _mockUnifiedOptinRepository;
|
||||
private Mock<IMemberPreferenceRepository> _mockMemberPreferenceRepository;
|
||||
private Mock<IFtpApiService> _mockFtpApiService;
|
||||
private ConnectionConfiguration _connectionConfiguration;
|
||||
private ReceiveEndpointConfiguration _completionReceiveEndpoint;
|
||||
private ReceiveEndpointConfigurations _endpointConfiguration;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mockBatchItemsRepository = new Mock<IXdiBatchItemsRepository>();
|
||||
_mockUnitOfWork = new Mock<IUnitOfWork>();
|
||||
_ftpConfiguration = new XdiSftpApiConfiguration();
|
||||
_mockUnifiedOptinRepository = new Mock<IUnifiedOptInRepository>();
|
||||
_mockMemberPreferenceRepository = new Mock<IMemberPreferenceRepository>();
|
||||
_mockFtpApiService = new Mock<IFtpApiService>();
|
||||
_endpointConfiguration = new ReceiveEndpointConfigurations();
|
||||
_completionReceiveEndpoint = _endpointConfiguration.XdiBatchConfirmEndpoint;
|
||||
|
||||
_xdiBatchItemService = new XdiBatchService(_mockBatchItemsRepository.Object, _mockUnitOfWork.Object,
|
||||
_ftpConfiguration, _mockUnifiedOptinRepository.Object, _mockMemberPreferenceRepository.Object,
|
||||
_connectionConfiguration, _endpointConfiguration, _mockFtpApiService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_Item_Exists()
|
||||
{
|
||||
var existing = new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
};
|
||||
_mockBatchItemsRepository.Setup(x => x.FindExistingItem(existing.UserId, existing.BatchState))
|
||||
.ReturnsAsync(existing);
|
||||
_mockBatchItemsRepository.Setup(x => x.Update(existing)).Verifiable();
|
||||
_mockBatchItemsRepository.Setup(x => x.SaveAsync(existing)).Verifiable();
|
||||
_mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable();
|
||||
|
||||
XdiBatchItem testItem = new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
};
|
||||
await _xdiBatchItemService.AddXdiBatchItem(testItem);
|
||||
|
||||
_mockBatchItemsRepository.Verify(x => x.FindExistingItem(existing.UserId, existing.BatchState),
|
||||
Times.Once);
|
||||
_mockBatchItemsRepository.Verify(x => x.Update(existing), Times.Once);
|
||||
_mockBatchItemsRepository.Verify(x => x.SaveAsync(existing), Times.Never);
|
||||
_mockUnitOfWork.Verify(x => x.CompleteAsync(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_Item_New()
|
||||
{
|
||||
_mockBatchItemsRepository.Setup(x => x.FindExistingItem(It.IsAny<string>(), It.IsAny<BatchState>()))
|
||||
.ReturnsAsync((XdiBatchItem)null);
|
||||
_mockBatchItemsRepository.Setup(x => x.Update(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
_mockBatchItemsRepository.Setup(x => x.SaveAsync(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
_mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable();
|
||||
|
||||
XdiBatchItem testItem = new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
};
|
||||
await _xdiBatchItemService.AddXdiBatchItem(testItem);
|
||||
|
||||
_mockBatchItemsRepository.Verify(x => x.FindExistingItem(It.IsAny<string>(), It.IsAny<BatchState>()),
|
||||
Times.Once);
|
||||
_mockBatchItemsRepository.Verify(x => x.Update(It.IsAny<XdiBatchItem>()), Times.Never);
|
||||
_mockBatchItemsRepository.Verify(x => x.SaveAsync(It.IsAny<XdiBatchItem>()), Times.Once);
|
||||
_mockUnitOfWork.Verify(x => x.CompleteAsync(), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_Create_Batch_Files()
|
||||
{
|
||||
IReadOnlyCollection<XdiBatchItem> items = new List<XdiBatchItem>()
|
||||
{
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "100"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "101"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "102"
|
||||
},
|
||||
//This is pending and we will process it again
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.TransferPending,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "103"
|
||||
}
|
||||
};
|
||||
|
||||
// Should be one of each type of change, resulting in a single line batch file for all types.
|
||||
var settings = new List<MemberOptInSettings>()
|
||||
{
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
LastUpdated = DateTime.Now,
|
||||
LegalDate = DateTime.Now,
|
||||
LegalVersion = "1.2.3",
|
||||
UserId = "99",
|
||||
CreatedByType = UserType.Associate,
|
||||
LastUpdatedByType = UserType.System,
|
||||
CreatedBy = "test",
|
||||
Created = DateTime.Now,
|
||||
LastUpdatedBy = "test"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1001,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "100"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1002,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Paper,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "101"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1003,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = null,
|
||||
UserId = "102"
|
||||
},
|
||||
new MemberOptInSettings()
|
||||
{
|
||||
Id = 1004,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "103"
|
||||
}
|
||||
};
|
||||
_mockBatchItemsRepository.Setup(x => x.GetXdiBatchItems()).ReturnsAsync(items);
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
_mockUnifiedOptinRepository.Setup(x => x.GetMemberOptInSettings(setting.UserId))
|
||||
.ReturnsAsync(setting);
|
||||
}
|
||||
|
||||
_mockBatchItemsRepository.Setup(x => x.Update(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
_mockBatchItemsRepository.Setup(x => x.Delete(It.IsAny<XdiBatchItem>())).Verifiable();
|
||||
_mockUnitOfWork.Setup(x => x.CompleteAsync(It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<UserType>()))
|
||||
.Verifiable();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateFtpQueryPayload_Ok()
|
||||
{
|
||||
var testFile = new XdiBatchFile
|
||||
{
|
||||
Data = new List<XdiBatchFileRow>
|
||||
{
|
||||
new XdiBatchFileRow {UserId = "100", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "101", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "102", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "103", Email = "[email protected]",}
|
||||
}
|
||||
};
|
||||
|
||||
IReadOnlyCollection<XdiBatchItem> items = new List<XdiBatchItem>()
|
||||
{
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "100"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "101"
|
||||
},
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "102"
|
||||
},
|
||||
//This is pending and we will process it again
|
||||
new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.TransferPending,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "103"
|
||||
}
|
||||
};
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking("100")).ReturnsAsync(new MemberOptInSettings
|
||||
{
|
||||
UserId = "100",
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]"
|
||||
});
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking("101")).ReturnsAsync(new MemberOptInSettings
|
||||
{
|
||||
UserId = "101",
|
||||
UniversalOptIn = DeliveryPreference.Paper
|
||||
});
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking("102")).ReturnsAsync(new MemberOptInSettings
|
||||
{
|
||||
UserId = "102",
|
||||
UniversalOptIn = DeliveryPreference.Microfiche
|
||||
});
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking("103")).ReturnsAsync(new MemberOptInSettings
|
||||
{
|
||||
UserId = "103",
|
||||
UniversalOptIn = DeliveryPreference.Hold
|
||||
});
|
||||
|
||||
var results = await _xdiBatchItemService.CreateFtpPayload(testFile);
|
||||
|
||||
Assert.AreEqual(4, results.Count);
|
||||
Assert.True(results.Exists(x => x.UserId == "100" && x.Value == "[email protected]"));
|
||||
Assert.True(results.Exists(x => x.UserId == "101" && x.Value == DeliveryPreference.Paper));
|
||||
Assert.True(results.Exists(x => x.UserId == "102" && x.Value == DeliveryPreference.Paper));
|
||||
Assert.True(results.Exists(x => x.UserId == "103" && x.Value == DeliveryPreference.Paper));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CreateFtpQueryPayload_No_Result_Ok()
|
||||
{
|
||||
var testFile = new XdiBatchFile
|
||||
{
|
||||
Data = new List<XdiBatchFileRow>
|
||||
{
|
||||
new XdiBatchFileRow {UserId = "100", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "101", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "102", Email = "[email protected]",},
|
||||
new XdiBatchFileRow {UserId = "103", Email = "[email protected]",}
|
||||
}
|
||||
};
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking("100")).ReturnsAsync(new MemberOptInSettings
|
||||
{
|
||||
UserId = "100",
|
||||
UniversalOptIn = DeliveryPreference.Paper
|
||||
}).Verifiable();
|
||||
|
||||
_mockUnifiedOptinRepository
|
||||
.Setup(x => x.GetMemberOptInSettingsNoTracking(It.Is<string>(userId => int.Parse(userId) > 100)))
|
||||
.Returns(Task.FromResult<MemberOptInSettings>(null));
|
||||
|
||||
var results = await _xdiBatchItemService.CreateFtpPayload(testFile);
|
||||
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.True(results.Exists(x => x.UserId == "100" && x.Value == DeliveryPreference.Paper));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MarkPendingSuccessful_OK()
|
||||
{
|
||||
var payload = new List<FtpQueuePayloadItem>()
|
||||
{
|
||||
new FtpQueuePayloadItem()
|
||||
{
|
||||
UserId = "100",
|
||||
Value = DeliveryPreference.Paper
|
||||
},
|
||||
new FtpQueuePayloadItem()
|
||||
{
|
||||
UserId = "101",
|
||||
Value = "[email protected]"
|
||||
}
|
||||
};
|
||||
var payloadString = JsonConvert.SerializeObject(payload);
|
||||
|
||||
var response = new LCU.Library.Internal.ApiResponse.Models.Response()
|
||||
{
|
||||
ResponsePayload = payloadString,
|
||||
Successful = true
|
||||
};
|
||||
|
||||
_mockMemberPreferenceRepository.Setup(x => x.SaveMemberPreferenceAsync(It.IsAny<MemberPreference>()))
|
||||
.Verifiable();
|
||||
_mockMemberPreferenceRepository
|
||||
.Setup(x => x.BulkSaveMemberPreferenceAsync(It.IsAny<List<MemberPreference>>())).Verifiable();
|
||||
_mockUnifiedOptinRepository.Setup(x => x.GetOrCreateMemberOptinSettings(It.IsAny<string>()))
|
||||
.ReturnsAsync(new MemberOptInSettings());
|
||||
_mockBatchItemsRepository.Setup(x => x.MarkPendingSuccessful(It.IsAny<List<string>>())).ReturnsAsync(true)
|
||||
.Verifiable();
|
||||
|
||||
var result = await _xdiBatchItemService.MarkPendingSuccessful(response);
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
_mockBatchItemsRepository.Verify(x =>
|
||||
x.MarkPendingSuccessful(It.Is<List<string>>(list =>
|
||||
list.Contains("100") && list.Contains("101"))));
|
||||
|
||||
_mockMemberPreferenceRepository.Verify(x => x.SaveMemberPreferenceAsync(It.Is<MemberPreference>(preference =>
|
||||
preference.UserId == "100" && preference.Value == DeliveryPreference.Paper)));
|
||||
|
||||
_mockMemberPreferenceRepository.Verify(x => x.BulkSaveMemberPreferenceAsync(It.Is<List<MemberPreference>>(
|
||||
preferenceList =>
|
||||
preferenceList.Exists(x => x.UserId == "101" && x.Value == DeliveryPreference.Electronic) &&
|
||||
preferenceList.Exists(x => x.UserId == "101" && x.Value == "[email protected]"))));
|
||||
|
||||
_mockMemberPreferenceRepository.Verify(x =>
|
||||
x.SaveMemberPreferenceAsync(It.IsAny<MemberPreference>()), Times.Once());
|
||||
|
||||
_mockMemberPreferenceRepository.Verify(x =>
|
||||
x.BulkSaveMemberPreferenceAsync(It.IsAny<List<MemberPreference>>()), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using NUnit.Framework;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests.XdiBatch
|
||||
{
|
||||
public class XdiBatchFileTest
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNewEnrollFile()
|
||||
{
|
||||
var newFile = new XdiBatchFile()
|
||||
{
|
||||
Type = XdiFileType.AddMemberElectronic,
|
||||
Data = new List<XdiBatchFileRow>()
|
||||
{
|
||||
new XdiBatchFileRow()
|
||||
{
|
||||
Email = "[email protected]",
|
||||
UserId = "99",
|
||||
CellPhone = ""
|
||||
},
|
||||
new XdiBatchFileRow()
|
||||
{
|
||||
Email = "[email protected]",
|
||||
UserId = "89",
|
||||
CellPhone = ""
|
||||
},
|
||||
new XdiBatchFileRow()
|
||||
{
|
||||
Email = "[email protected]",
|
||||
UserId = "79",
|
||||
CellPhone = ""
|
||||
}
|
||||
}
|
||||
};
|
||||
var fileName = newFile.GetFileName();
|
||||
var stringResults = newFile.ConvertToDataRows();
|
||||
|
||||
var results = newFile.ConvertToDataFile();
|
||||
|
||||
Assert.NotNull(fileName);
|
||||
Assert.AreEqual("Enrollment_AddElectronic_LMCU.txt", fileName);
|
||||
|
||||
Assert.NotNull(results);
|
||||
Assert.NotNull(stringResults);
|
||||
Assert.AreEqual("99|[email protected]|", stringResults.First());
|
||||
}
|
||||
}
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.UnitTests
|
||||
{
|
||||
public class XdiBatchTest
|
||||
{
|
||||
private XdiBatchItem _item;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_item = new XdiBatchItem()
|
||||
{
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now,
|
||||
UserId = "99"
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEmptyBatch()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.False(files.Any());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_UpdateToPrint()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
LastUpdated = DateTime.Now,
|
||||
LegalDate = DateTime.Now,
|
||||
LegalVersion = "1.2.3",
|
||||
UserId = "99",
|
||||
CreatedByType = UserType.Associate,
|
||||
LastUpdatedByType = UserType.System,
|
||||
CreatedBy = "test",
|
||||
Created = DateTime.Now,
|
||||
LastUpdatedBy = "test"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.UpdateMemberToPrint, files.First().Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_DoNothing()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Paper,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.False(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.False(files.Any());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_UpdateToElectronic()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Paper,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.UpdateMemberToElectronic, files.First().Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_AddElectronic()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = null,
|
||||
EStatements = DeliveryPreference.Paper,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = null,
|
||||
EStatementsEmail = null,
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.AddMemberElectronic, files.First().Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_UpdateEmail()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Electronic,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.UpdateMemberEmail, files.First().Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_Microfiche()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Microfiche,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.UpdateMemberToPrint, files.First().Type);
|
||||
Assert.AreEqual("[email protected]", files.First().Data.First().Email);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Enrollment_Hold()
|
||||
{
|
||||
var batch = new Models.XdiBatch();
|
||||
var settings = new MemberOptInSettings()
|
||||
{
|
||||
Id = 1000,
|
||||
UniversalOptIn = DeliveryPreference.Hold,
|
||||
ENotifications = DeliveryPreference.Electronic,
|
||||
EStatements = DeliveryPreference.Electronic,
|
||||
UnifiedOptInEmail = "[email protected]",
|
||||
ENotificationsEmail = "[email protected]",
|
||||
EStatementsEmail = "[email protected]",
|
||||
UserId = "99"
|
||||
};
|
||||
|
||||
var result = batch.ProcessItem(_item, settings);
|
||||
|
||||
Assert.True(result);
|
||||
var files = batch.GetNonEmptyFiles();
|
||||
Assert.NotNull(files);
|
||||
Assert.AreEqual(1, files.Count);
|
||||
Assert.AreEqual(XdiFileType.UpdateMemberToPrint, files.First().Type);
|
||||
Assert.AreEqual("[email protected]", files.First().Data.First().Email);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.Library.Internal.MemberPreferencesApiModels", "LCU.Library.Internal.MemberPreferencesApiModels\LCU.Library.Internal.MemberPreferencesApiModels.csproj", "{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.MemberPreferencesApi", "LCU.API.Internal.MemberPreferencesApi\LCU.API.Internal.MemberPreferencesApi.csproj", "{DD45BE57-F5EC-4FB5-957D-1018840110F9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.MemberPreferencesApi.IntegrationTests", "LCU.API.Internal.MemberPreferencesApi.IntegrationTests\LCU.API.Internal.MemberPreferencesApi.IntegrationTests.csproj", "{ACEED8EE-3199-4E63-95CF-E229BC4BA501}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.MemberPreferencesApi.UnitTests", "LCU.API.Internal.MemberPreferencesApi.UnitTests\LCU.API.Internal.MemberPreferencesApi.UnitTests.csproj", "{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}"
|
||||
EndProject
|
||||
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "LCU.API.Internal.MemberPreferencesApiSql", "LCU.API.Internal.MemberPreferencesApiSql\LCU.API.Internal.MemberPreferencesApiSql.sqlproj", "{E747B744-2EE4-494C-918A-10AB7CBF3844}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LCU.API.Internal.MemberPreferencesApiLib", "LCU.API.Internal.MemberPreferencesApiLib\LCU.API.Internal.MemberPreferencesApiLib.csproj", "{597C781A-D012-4D7E-B7D5-275566684D61}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B5CB3C54-9DC4-4D0A-80BB-0DA67BB716BF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DD45BE57-F5EC-4FB5-957D-1018840110F9}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|x64.Build.0 = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ACEED8EE-3199-4E63-95CF-E229BC4BA501}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E23E5E87-B4C2-4EA0-AD9E-C08E8A47D3C5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x64.Deploy.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Debug|x86.Deploy.0 = Debug|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x64.Deploy.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E747B744-2EE4-494C-918A-10AB7CBF3844}.Release|x86.Deploy.0 = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|x64.Build.0 = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{597C781A-D012-4D7E-B7D5-275566684D61}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {27AEB349-C311-4841-B6F0-18C03AAB44BE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class ApiConfiguration
|
||||
{
|
||||
public string AppName { get; set; }
|
||||
public string SeqUrl { get; set; }
|
||||
public string SeqKey { get; set; }
|
||||
public string[] CorsAllowedOrigins { get; set; }
|
||||
public FeatureFlags FeatureFlags { get; set; }
|
||||
public FeatureGates FeatureGates { get; set; }
|
||||
public string XdiBatchProcessCronSchedule { get; set; }
|
||||
public string DnaDataAuditProcessCronSchedule { get; set; }
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class CoreApiWrapperConfiguration
|
||||
{
|
||||
public string CoreApiBaseUrl { get; set; }
|
||||
public string CoreApiGetAgreementByUserId { get; set; }
|
||||
public string CoreApiGetAgreementByAgreementId { get; set; }
|
||||
public string CoreApiGetAgreementsByAccountId { get; set; }
|
||||
public string CoreApiGetAgreementAccountByAccountId { get; set; }
|
||||
public string CoreApiGetAgreementAccountsByUserId { get; set; }
|
||||
public string CoreApiGetAgreementAccountsByOrganizationId { get; set; }
|
||||
public string CoreApiGetAuditAccountsFromDateLastMaintained { get; set; }
|
||||
public string CoreApiGetAuditAgreementFromDateLastMaintained { get; set; }
|
||||
public string CoreApiGetAuditOrganizationFromDateLastMaintained { get; set; }
|
||||
public string CoreApiUpdateAccountsMaintenanceRequest { get; set; }
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class DnaAuditProcessConfiguration
|
||||
{
|
||||
public int LookBackMinutes { get; set; }
|
||||
public int NumberOfAllowedConsecutiveFailures { get; set; }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class FeatureFlags
|
||||
{
|
||||
public bool RunHostedServices { get; set; }
|
||||
public bool RunXdiBatchProcessConsumer { get; set; }
|
||||
public bool RunXdiSshResponseConsumer { get; set; }
|
||||
public bool RunAccountDnaFieldChangeConsumer { get; set; }
|
||||
public bool RunAgreementDnaFieldChangeConsumer { get; set; }
|
||||
public bool RunOrganizationDnaFieldChangeConsumer { get; set; }
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class FeatureGates
|
||||
{
|
||||
public const string EnableControllers = "EnableControllers";
|
||||
public const string BounceBackNotifications = "BounceBackNotifications";
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class FtpApiConfiguration
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string QueueSshFtpRequestEndpoint { get; set; }
|
||||
[NotMapped]
|
||||
public string QueueSshFtpRequestEndpointUrl => Url + QueueSshFtpRequestEndpoint;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class NotificationApiConfiguration
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string Email { get; set; }
|
||||
public int RetryCount { get; set; }
|
||||
[NotMapped]
|
||||
public string EmailUrl => Url + Email;
|
||||
public List<string> DNACoreErrorEmailList { get; set; }
|
||||
public List<string> TestEmailList { get; set; }
|
||||
public bool ShouldSendRealEmails { get; set; }
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class ReceiveEndpointConfigurations
|
||||
{
|
||||
public ReceiveEndpointConfiguration XdiBatchProcessEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration XdiBatchConfirmEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration DnaAccountAuditEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration DnaOrganizationAuditEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration DnaAgreementAuditEndpoint { get; set; }
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class SqlConnectionConfiguration
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
public int MaxRetryCount { get; set; }
|
||||
public TimeSpan MaxRetryDelay { get; set; }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Configuration;
|
||||
|
||||
public class XdiSftpApiConfiguration
|
||||
{
|
||||
public string HostName { get; set; }
|
||||
public int PortNumber { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Fingerprint { get; set; }
|
||||
public string SftpRootBasePath { get; set; }
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
|
||||
public class AccountDnaFieldChangeConsumer : IConsumer<DnaFieldChangeRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public AccountDnaFieldChangeConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<DnaFieldChangeRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting AccountDnaFieldChangeConsumer.");
|
||||
Log.Information($"New Account Received for: {context.Message.DnaProcessType} Process - {context.Message.DnaFieldIdInformation}");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IDNADataAuditService>().HandleAccountAuditCheck(context.Message));
|
||||
Log.Debug("Ending DnaAccountAuditServiceConsumer.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"AccountDnaFieldChangeConsumer Failure. " +
|
||||
$"The request is placed on AccountDnaFieldChangeConsumer_error.");
|
||||
throw serviceException;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected AccountDnaFieldChangeConsumer Failure. " +
|
||||
$"The request is placed on AccountDnaFieldChangeConsumer_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
|
||||
public class AgreementDnaFieldChangeConsumer : IConsumer<DnaFieldChangeRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public AgreementDnaFieldChangeConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<DnaFieldChangeRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting AgreementDnaFieldChangeConsumer.");
|
||||
Log.Information($"New Agreement Received for : {context.Message.DnaProcessType} Process - {context.Message.DnaFieldIdInformation}");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IDNADataAuditService>().HandleAgreementAuditCheck(context.Message));
|
||||
Log.Debug("Ending AgreementDnaFieldChangeConsumer.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"AgreementDnaFieldChangeConsumer Failure. " +
|
||||
$"The request is placed on AgreementDnaFieldChangeConsumer_error.");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected AgreementDnaFieldChangeConsumer Failure. " +
|
||||
$"The TransactionRequest is placed on AgreementDnaFieldChangeConsumer_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
|
||||
public class OrganizationDnaFieldChangeConsumer : IConsumer<DnaFieldChangeRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public OrganizationDnaFieldChangeConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<DnaFieldChangeRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Debug("Starting OrganizationDnaFieldChangeConsumer.");
|
||||
Log.Information($"New Organization Received for: {context.Message.DnaProcessType} Process - {context.Message.DnaFieldIdInformation}");
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IDNADataAuditService>().HandleOrganizationAuditCheck(context.Message));
|
||||
Log.Debug("Ending OrganizationDnaFieldChangeConsumer.");
|
||||
}
|
||||
catch (ServiceException serviceException)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(serviceException, $"OrganizationDnaFieldChangeConsumer Failure. " +
|
||||
$"The request is placed on OrganizationDnaFieldChangeConsumer_error.");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected OrganizationDnaFieldChangeConsumer Consumer Failure. " +
|
||||
$"The request is placed on OrganizationDnaFieldChangeConsumer_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
|
||||
public class XdiBatchProcessConsumer : IConsumer<XdiBatchRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
public XdiBatchProcessConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
public async Task Consume(ConsumeContext<XdiBatchRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IXdiBatchService>().CreateXdiBatchFiles(context.Message));
|
||||
}
|
||||
catch (ServiceException ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error($"XdiBatchProcessConsumer Failure. " +
|
||||
$"The response is placed on LCU.MemberPreferencesApi.XdiAuditProcess_error. " +
|
||||
$"Error Message: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected XdiBatchProcessConsumer Failure. " +
|
||||
$"The response is placed on LCU.MemberPreferencesApi.XdiAuditProcess_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
|
||||
public class XdiSshResponseConsumer : IConsumer<ApiResponse.Response>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
public XdiSshResponseConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
public async Task Consume(ConsumeContext<ApiResponse.Response> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IXdiBatchService>().MarkPendingSuccessful(context.Message));
|
||||
}
|
||||
catch (ServiceException ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error($"XdiSshResponseConsumer Failure. " +
|
||||
$"The ApiResponse.Response is placed on LCU.MemberPreferencesApi.XdiBatchConfirm_error. " +
|
||||
$"Error Message: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected XdiSshResponseConsumer Failure. " +
|
||||
$"The ApiResponse.Response is placed on LCU.MemberPreferencesApi.XdiBatchConfirm_error.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class AuditController : ControllerBase
|
||||
{
|
||||
private readonly IQueueDnaAccountAuditService _dnaAccountAuditService;
|
||||
private readonly IQueueDnaOrganizationAuditService _dnaOrganizationAuditService;
|
||||
private readonly IQueueDnaAgreementAuditService _dnaAgreementAuditService;
|
||||
|
||||
public AuditController(IQueueDnaAccountAuditService dnaAccountAuditService,
|
||||
IQueueDnaOrganizationAuditService dnaOrganizationAuditService,
|
||||
IQueueDnaAgreementAuditService dnaAgreementAuditService)
|
||||
{
|
||||
_dnaAccountAuditService = dnaAccountAuditService;
|
||||
_dnaOrganizationAuditService = dnaOrganizationAuditService;
|
||||
_dnaAgreementAuditService = dnaAgreementAuditService;
|
||||
}
|
||||
|
||||
[HttpPost("EnqueueDNAOrganizationAuditRecords")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> EnqueueDNAOrganizationAuditRecords([FromBody] List<long> organizationIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Information($"Forced {organizationIds.Count} DNAOrganizationAuditRecords to be queued");
|
||||
await _dnaOrganizationAuditService.QueueDataAuditForOrganizations(organizationIds);
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}");
|
||||
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("EnqueueDNAAgreementAuditRecords")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> EnqueueDNAAgreementAuditRecords([FromBody] List<long> agreementIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Information($"Forced {agreementIds.Count} DNAAgreementAuditRecords to be queued");
|
||||
await _dnaAgreementAuditService.QueueDataAuditForAgreements(agreementIds);
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}");
|
||||
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("EnqueueDNAAccountAuditRecords")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> EnqueueDNAAccountAuditRecords([FromBody] List<long> accountNumbers)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Information($"Forced {accountNumbers.Count} DNAAccountAuditRecords to be queued");
|
||||
await _dnaAccountAuditService.QueueDataAuditForAccounts(accountNumbers);
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}");
|
||||
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.FeatureManagement;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Controllers
|
||||
{
|
||||
[Route("api/{userId}")]
|
||||
[ApiController]
|
||||
public class MemberEmailController : ControllerBase
|
||||
{
|
||||
private readonly IMemberEmailService _emailService;
|
||||
private readonly IFeatureManager _featureManager;
|
||||
|
||||
public MemberEmailController(IMemberEmailService emailService,
|
||||
IFeatureManager featureManager)
|
||||
{
|
||||
_emailService = emailService;
|
||||
_featureManager = featureManager;
|
||||
}
|
||||
|
||||
[HttpPost("SuccessfulSend")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
[ReadsCurrentUser]
|
||||
public async Task<IActionResult> EmailSentSuccessfully(string userId, [FromQuery] string email)
|
||||
{
|
||||
var emailUpdated = await _emailService.EmailSucceededToSend(userId, email);
|
||||
|
||||
if (!emailUpdated)
|
||||
{
|
||||
return NotFound($"unknown email {email} for {userId}");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("FailedSend")]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(404)]
|
||||
[ReadsCurrentUser]
|
||||
public async Task<IActionResult> EmailSendFailed(string userId, [FromQuery] string email)
|
||||
{
|
||||
|
||||
var enablePolicy = await _featureManager.IsEnabledAsync(FeatureGates.BounceBackNotifications);
|
||||
var emailUpdated = await _emailService.EmailFailedToSend(userId, email, enablePolicy);
|
||||
|
||||
if (!emailUpdated)
|
||||
{
|
||||
return NotFound($"unknown email {email} for {userId}");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.DataTransfer;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.FeatureManagement.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
|
||||
[FeatureGate(FeatureGates.EnableControllers)]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class MemberOptInSettingsController : ControllerBase
|
||||
{
|
||||
private readonly IOptinService _unifiedOptinService;
|
||||
private readonly IMemberPreferenceService _memberPreferenceService;
|
||||
|
||||
public MemberOptInSettingsController(IOptinService unifiedOptinService,
|
||||
IMemberPreferenceService memberPreferenceService)
|
||||
{
|
||||
_unifiedOptinService = unifiedOptinService;
|
||||
_memberPreferenceService = memberPreferenceService;
|
||||
}
|
||||
|
||||
[HttpGet("AgreementInformationForAccount/{accountId:long}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<MemberOptInAgreementInformation>), 200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetAgreementsByAccountId(long accountId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (accountId == 0)
|
||||
{
|
||||
return BadRequest("An account id must be provided to search by, and cannot be 0.");
|
||||
}
|
||||
|
||||
var result = await _unifiedOptinService.GetMemberOptInAgreementInformationByAccountId(accountId);
|
||||
|
||||
if (result != null && result.Any())
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
return NotFound($"No Opt-In Agreement Settings found for accountId:{accountId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}.");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("AgreementInformation/{userId}")]
|
||||
[ProducesResponseType(typeof(MemberOptInAgreementInformation), 200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetAgreementByUserId(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return BadRequest("An UserId id must be provided to search by.");
|
||||
}
|
||||
|
||||
var result = await _unifiedOptinService.GetMemberOptInAgreementInformationForUser(userId);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
return NotFound($"No Opt-In Agreement Settings found for userId:{userId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}.");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{userId}")]
|
||||
[ProducesResponseType(typeof(MemberOptInInformation), 200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetMemberById(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return BadRequest("An user id must be provided to search by and cannot be 0.");
|
||||
}
|
||||
|
||||
var result = await _unifiedOptinService.GetMemberOptInSettingsOrCreateDefaultSetting(userId);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
var memberOptinSettings = await _unifiedOptinService.TransformMemberOptInSettingsForClient(result);
|
||||
return Ok(memberOptinSettings);
|
||||
}
|
||||
|
||||
return NotFound($"Requested Opt-In Settings for {userId} were not found.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}.");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> UpdateOptinPreference(MemberOptinRequest memberPreference,
|
||||
[FromHeader] string userName, [FromHeader] string userType)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(userType))
|
||||
{
|
||||
return BadRequest("Missing User Headers");
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
await _memberPreferenceService.UpdateMemberOptinAsync(memberPreference);
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}.");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.FeatureManagement.Mvc;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Controllers;
|
||||
|
||||
[FeatureGate(FeatureGates.EnableControllers)]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class MemberPreferenceController : ControllerBase
|
||||
{
|
||||
private readonly IMemberPreferenceService _memberPreferenceService;
|
||||
|
||||
public MemberPreferenceController(IMemberPreferenceService memberPreferenceService)
|
||||
{
|
||||
_memberPreferenceService = memberPreferenceService;
|
||||
}
|
||||
|
||||
[HttpGet("AvailableTypes")]
|
||||
public IActionResult GetAvailableTypes()
|
||||
{
|
||||
return Ok(_memberPreferenceService.GetAvailableTypes());
|
||||
}
|
||||
|
||||
[HttpGet("{userId}")]
|
||||
public async Task<IActionResult> Get(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _memberPreferenceService.GetMemberPreferencesAsync(userId);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateMemberPreference(MemberPreferenceRequest memberPreference,
|
||||
[FromHeader] string userName, [FromHeader] string userType)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(userType))
|
||||
{
|
||||
return BadRequest("Missing User Headers");
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var result = await _memberPreferenceService.SaveMemberPreferenceAsync(memberPreference);
|
||||
return CreatedAtAction(nameof(CreateMemberPreference), new {userId = memberPreference.UserId}, memberPreference);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure in {GetType().Name}.");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using LCU.Library.Internal.Status.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class StatusController : ControllerBase
|
||||
{
|
||||
private readonly IApiHealthCheckService _apiHealthCheckService;
|
||||
|
||||
public StatusController(IApiHealthCheckService apiHealthCheckService)
|
||||
{
|
||||
_apiHealthCheckService = apiHealthCheckService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(_apiHealthCheckService.CheckApiHealthAndBuildEnvironmentView());
|
||||
}
|
||||
catch (ServiceException exception)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using LCU.Library.Internal.ApiSecurity.Enums;
|
||||
using LCU.Library.Internal.ApiSecurity.Models;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.CoreRequests;
|
||||
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
|
||||
using LCU.Library.Internal.LcuHttpClient.Utilities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public class CoreApiWrapperDao : ICoreApiWrapperDao
|
||||
{
|
||||
private readonly ApiSecurityConfiguration _apiSecurityConfiguration;
|
||||
private readonly CoreApiWrapperConfiguration _coreApiWrapperConfig;
|
||||
private readonly IGetRequest _getRequest;
|
||||
private readonly IPutRequest _putRequest;
|
||||
private static readonly List<string> AccountTypesToFilterOut = new List<string> { "EXT", "BKCK", "RTMT", "RR", "LEAS" };
|
||||
|
||||
private const string ClientKeyValue = "MembershipPreferences";
|
||||
|
||||
public CoreApiWrapperDao(ApiSecurityConfiguration apiSecurityConfiguration, CoreApiWrapperConfiguration coreApiWrapperConfig,
|
||||
IGetRequest getRequest, IPutRequest putRequest)
|
||||
{
|
||||
_apiSecurityConfiguration = apiSecurityConfiguration;
|
||||
_coreApiWrapperConfig = coreApiWrapperConfig;
|
||||
_getRequest = getRequest;
|
||||
_putRequest = putRequest;
|
||||
}
|
||||
|
||||
public async Task<Agreement> GetAgreementByUserId(string userId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementByUserId.Replace("{userId}", userId)}";
|
||||
return await _getRequest.Async<Agreement>(path, 0);
|
||||
}
|
||||
|
||||
public async Task<Agreement> GetAgreementByAgreementId(long agreementId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementByAgreementId.Replace("{agreementId}", agreementId.ToString())}";
|
||||
return await _getRequest.Async<Agreement>(path, 0);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Agreement>> GetAgreementsByAccountId(long accountId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementsByAccountId.Replace("{accountId}", accountId.ToString())}";
|
||||
return await _getRequest.Async<IEnumerable<Agreement>>(path, 0);
|
||||
}
|
||||
|
||||
public async Task<AgreementAccount> GetAgreementAccountByAccountId(long accountId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementAccountByAccountId.Replace("{accountId}", accountId.ToString())}";
|
||||
var response = await _getRequest.Async<AgreementAccount>(path, 0);
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return AccountTypesToFilterOut.Contains(response.MajorAccountTypeCode) ? null : response;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByUserId(string userId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementAccountsByUserId.Replace("{userId}", userId)}";
|
||||
var response = await _getRequest.Async<IEnumerable<AgreementAccount>>(path, 0);
|
||||
return response.Where(account => !AccountTypesToFilterOut.Contains(account.MajorAccountTypeCode));
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByOrganizationId(long organizationId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAgreementAccountsByOrganizationId.Replace("{organizationId}", organizationId.ToString())}";
|
||||
var response = await _getRequest.Async<IEnumerable<AgreementAccount>>(path, 0);
|
||||
return response.Where(account => !AccountTypesToFilterOut.Contains(account.MajorAccountTypeCode));
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditAccountsFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
var dtString = dateTime.ToString("s").Replace(":", "%3A");
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAuditAccountsFromDateLastMaintained}?dateLastMaintained={dtString}";
|
||||
return await _getRequest.Async<IEnumerable<long>>(path, 0, 240);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditAgreementFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
var dtString = dateTime.ToString("s").Replace(":", "%3A");
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAuditAgreementFromDateLastMaintained}?dateLastMaintained={dtString}";
|
||||
return await _getRequest.Async<IEnumerable<long>>(path, 0, 240);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditOrganizationFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
var dtString = dateTime.ToString("s").Replace(":", "%3A");
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiGetAuditOrganizationFromDateLastMaintained}?dateLastMaintained={dtString}";
|
||||
return await _getRequest.Async<IEnumerable<long>>(path, 0, 240);
|
||||
}
|
||||
|
||||
public async Task UpdateAgreementAccountsDeliveryMethod(IEnumerable<long> accountIds, string deliveryMethod, string userId)
|
||||
{
|
||||
var path = $"{_coreApiWrapperConfig.CoreApiBaseUrl}{_coreApiWrapperConfig.CoreApiUpdateAccountsMaintenanceRequest}";
|
||||
var uri = new Uri(path);
|
||||
|
||||
var accountMaintenanceRequests = new List<AccountMaintenanceRequest>();
|
||||
foreach (var accountId in accountIds)
|
||||
{
|
||||
var accountMaintenanceRequest = new AccountMaintenanceRequest
|
||||
{
|
||||
AccountNumber = accountId,
|
||||
DeliveryMethod = deliveryMethod
|
||||
};
|
||||
accountMaintenanceRequests.Add(accountMaintenanceRequest);
|
||||
}
|
||||
|
||||
await _putRequest.Async(uri, accountMaintenanceRequests, HttpUtilities.GetApiKeyHeaders(ClientKeyValue,
|
||||
_apiSecurityConfiguration.ExtractApiKey(ClientKeyValue, ApiKeySetName.InternalKeySet)), 0);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public class FtpApiDao : IFtpApiDao
|
||||
{
|
||||
private readonly FtpApiConfiguration _ftpApiConfiguration;
|
||||
private readonly IPostRequest _postRequest;
|
||||
|
||||
public FtpApiDao(FtpApiConfiguration ftpApiConfiguration, IPostRequest postRequest)
|
||||
{
|
||||
_ftpApiConfiguration = ftpApiConfiguration;
|
||||
_postRequest = postRequest;
|
||||
}
|
||||
|
||||
public async Task SendFtpAsync(SshFtpRequest request)
|
||||
{
|
||||
await _postRequest.Async(new Uri(_ftpApiConfiguration.QueueSshFtpRequestEndpointUrl), request, 0);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public interface ICoreApiWrapperDao
|
||||
{
|
||||
public Task<Agreement> GetAgreementByUserId(string userId);
|
||||
public Task<Agreement> GetAgreementByAgreementId(long agreementId);
|
||||
public Task<IEnumerable<Agreement>> GetAgreementsByAccountId(long accountId);
|
||||
public Task<AgreementAccount> GetAgreementAccountByAccountId(long accountId);
|
||||
public Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByUserId(string userId);
|
||||
public Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByOrganizationId(long organizationId);
|
||||
public Task<IEnumerable<long>> GetAuditAccountsFromDateLastMaintained(DateTime dateTime);
|
||||
public Task<IEnumerable<long>> GetAuditAgreementFromDateLastMaintained(DateTime dateTime);
|
||||
public Task<IEnumerable<long>> GetAuditOrganizationFromDateLastMaintained(DateTime dateTime);
|
||||
public Task UpdateAgreementAccountsDeliveryMethod(IEnumerable<long> accountIds, string deliveryMethod, string userId);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public interface IFtpApiDao
|
||||
{
|
||||
public Task SendFtpAsync(SshFtpRequest sftpRequest);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public interface INotificationApiDao
|
||||
{
|
||||
public Task SendEmailAsync(EmailRequest emailRequest);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
public class NotificationApiDao : INotificationApiDao
|
||||
{
|
||||
private readonly NotificationApiConfiguration _notificationApiConfiguration;
|
||||
private readonly IPostRequest _postRequest;
|
||||
|
||||
public NotificationApiDao(NotificationApiConfiguration notificationApiConfiguration, IPostRequest postRequest)
|
||||
{
|
||||
_notificationApiConfiguration = notificationApiConfiguration;
|
||||
_postRequest = postRequest;
|
||||
}
|
||||
|
||||
public async Task SendEmailAsync(EmailRequest emailRequest)
|
||||
{
|
||||
await _postRequest.Async(new Uri(_notificationApiConfiguration.EmailUrl), emailRequest, _notificationApiConfiguration.RetryCount);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Api.Internal.FTPLib" Version="2.11.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.ApiSecurity" Version="1.0.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.Configuration" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.CoreApiWrapperModel" Version="2.27.14" />
|
||||
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.2" />
|
||||
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuHttpClient" Version="1.21.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Logging" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Status" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.StatusModels" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.FeatureManagement" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.FeatureManagement.AspNetCore" Version="2.6.0" />
|
||||
<PackageReference Include="NCrontab.Signed" Version="3.3.3" />
|
||||
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
<PackageReference Include="TimeZoneConverter" Version="3.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.API.Internal.MemberPreferencesApiLib\LCU.API.Internal.MemberPreferencesApiLib.csproj" />
|
||||
<ProjectReference Include="..\LCU.Library.Internal.MemberPreferencesApiModels\LCU.Library.Internal.MemberPreferencesApiModels.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Properties\launchSettings.json">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
|
||||
public class EStatementsSixtyDaysUndeliverableEmailPolicy : SixtyDaysUndeliverableEmailPolicy
|
||||
{
|
||||
protected override EmailStatus? Status => UserOptIn.EStatementsEmailStatus;
|
||||
protected override DateTime FirstUndeliverable => UserOptIn.EStatementsEmailFirstSent!.Value;
|
||||
protected override DateTime LastUndeliverable => UserOptIn.EStatementsEmailLastSent!.Value;
|
||||
protected override PreferenceType PreferenceType => PreferenceType.EStatements;
|
||||
protected override bool EligibleForPreferenceFlip => !UserOptIn.HasAnyUnifiedPreference() && UserOptIn.EStatements == "Electronic";
|
||||
protected override string Preference
|
||||
{
|
||||
set => UserOptIn.UniversalOptIn = value;
|
||||
}
|
||||
|
||||
public EStatementsSixtyDaysUndeliverableEmailPolicy(IAuditableChanges auditableTracker, IMemberPreferences memberPreferences)
|
||||
: base(auditableTracker, memberPreferences)
|
||||
{
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
|
||||
public interface IEmailFailurePolicy
|
||||
{
|
||||
public Task<bool> Apply(MemberOptInSettings userOptIn, bool enablePolicy);
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Models;
|
||||
using Serilog;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
|
||||
public abstract class SixtyDaysUndeliverableEmailPolicy : IEmailFailurePolicy
|
||||
{
|
||||
private const string UpdatedByUser = "BounceBackLimitReached";
|
||||
private readonly IAuditableChanges _auditableTracker;
|
||||
private readonly IMemberPreferences _memberPreferences;
|
||||
|
||||
protected MemberOptInSettings UserOptIn { get; private set; }
|
||||
protected abstract EmailStatus? Status { get; }
|
||||
protected abstract DateTime FirstUndeliverable { get; }
|
||||
protected abstract DateTime LastUndeliverable { get; }
|
||||
protected abstract string Preference { set; }
|
||||
protected abstract PreferenceType PreferenceType { get; }
|
||||
protected abstract bool EligibleForPreferenceFlip { get; }
|
||||
|
||||
protected SixtyDaysUndeliverableEmailPolicy(IAuditableChanges auditableTracker, IMemberPreferences memberPreferences)
|
||||
{
|
||||
_auditableTracker = auditableTracker;
|
||||
_memberPreferences = memberPreferences;
|
||||
}
|
||||
|
||||
public async Task<bool> Apply(MemberOptInSettings userOptIn, bool enablePolicy)
|
||||
{
|
||||
if (!enablePolicy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UserOptIn = userOptIn;
|
||||
|
||||
if (Status != EmailStatus.FailingDelivery)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((LastUndeliverable - FirstUndeliverable).Days < 60)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EligibleForPreferenceFlip)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var preferenceChange = new MemberPreference
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
UserId = userOptIn.UserId,
|
||||
LastUpdatedBy = userOptIn.LastUpdatedBy = UpdatedByUser,
|
||||
Value = Preference = DeliveryPreference.Paper,
|
||||
Created = DateTime.UtcNow,
|
||||
CreatedByType = UserType.System,
|
||||
LastUpdated = DateTime.UtcNow,
|
||||
LegalReference = UpdatedByUser
|
||||
};
|
||||
|
||||
await _memberPreferences.Add(preferenceChange);
|
||||
Log.Information($"UserId: {userOptIn.UserId} has reached BounceBack status from failed delivery of {PreferenceType} email: UniversalOptIn set to Paper.");
|
||||
|
||||
_auditableTracker.SystemModified(preferenceChange, preferenceChange.LastUpdatedBy);
|
||||
_auditableTracker.SystemModified(userOptIn, preferenceChange.LastUpdatedBy);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Models;
|
||||
using System;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
|
||||
public class UnifiedSixtyDaysUndeliverableEmailPolicy : SixtyDaysUndeliverableEmailPolicy
|
||||
{
|
||||
protected override EmailStatus? Status => UserOptIn.UnifiedOptInEmailStatus;
|
||||
protected override DateTime FirstUndeliverable => UserOptIn.UnifiedOptInEmailFirstSent!.Value;
|
||||
protected override DateTime LastUndeliverable => UserOptIn.UnifiedOptInEmailLastSent!.Value;
|
||||
protected override PreferenceType PreferenceType => PreferenceType.UnifiedOptIn;
|
||||
protected override bool EligibleForPreferenceFlip => UserOptIn.UniversalOptIn == "Electronic";
|
||||
|
||||
protected override string Preference
|
||||
{
|
||||
set => UserOptIn.UniversalOptIn = value;
|
||||
}
|
||||
|
||||
public UnifiedSixtyDaysUndeliverableEmailPolicy(IAuditableChanges auditableTracker, IMemberPreferences memberPreferences)
|
||||
: base(auditableTracker, memberPreferences)
|
||||
{
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
public class FtpQueuePayloadItem
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.Requests;
|
||||
|
||||
public class DnaFieldChangeRequest
|
||||
{
|
||||
public long DnaFieldIdInformation { get; set; }
|
||||
public int ProcessId { get; set; }
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public DnaAuditProcessType DnaProcessType { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
public int ConsecutiveFailures { get; set; }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.Requests;
|
||||
|
||||
public class EmailRequest
|
||||
{
|
||||
[Required] public List<string> Recipient { get; set; }
|
||||
[Required] public string Subject { get; set; }
|
||||
[Required] public string Body { get; set; }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.Requests;
|
||||
|
||||
public class XdiBatchRequest
|
||||
{
|
||||
public List<XdiBatchItem> XdiBatchItems { get; set; }
|
||||
public XdiBatch XdiBatch { get; set; }
|
||||
public string SftpRootBasePath { get; set; }
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models.Requests;
|
||||
|
||||
public class XdiBatchRequests
|
||||
{
|
||||
public List<XdiBatchRequest> XdiBatchRequestList { get; set; }
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
public class XdiBatch
|
||||
{
|
||||
private readonly XdiBatchFile _addMemberElectronic;
|
||||
private readonly XdiBatchFile _updateMemberEmail;
|
||||
private readonly XdiBatchFile _updateMemberToElectronic;
|
||||
private readonly XdiBatchFile _updateMemberToPrint;
|
||||
|
||||
public XdiBatch()
|
||||
{
|
||||
_addMemberElectronic = new XdiBatchFile()
|
||||
{
|
||||
Type = XdiFileType.AddMemberElectronic
|
||||
};
|
||||
_updateMemberEmail = new XdiBatchFile()
|
||||
{
|
||||
Type = XdiFileType.UpdateMemberEmail
|
||||
};
|
||||
_updateMemberToElectronic = new XdiBatchFile()
|
||||
{
|
||||
Type = XdiFileType.UpdateMemberToElectronic
|
||||
};
|
||||
_updateMemberToPrint = new XdiBatchFile()
|
||||
{
|
||||
Type = XdiFileType.UpdateMemberToPrint
|
||||
};
|
||||
}
|
||||
|
||||
public bool ProcessItem(XdiBatchItem item, MemberOptInSettings currentSettings)
|
||||
{
|
||||
if (currentSettings.UniversalOptIn == DeliveryPreference.Paper &&
|
||||
currentSettings.ENotifications == DeliveryPreference.Electronic)
|
||||
{
|
||||
_updateMemberToPrint.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentSettings.UniversalOptIn == DeliveryPreference.Electronic &&
|
||||
currentSettings.ENotifications != DeliveryPreference.Electronic)
|
||||
{
|
||||
if (currentSettings.ENotifications == DeliveryPreference.Paper)
|
||||
{
|
||||
_updateMemberToElectronic.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
_addMemberElectronic.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentSettings.UniversalOptIn == DeliveryPreference.Electronic &&
|
||||
currentSettings.ENotifications == DeliveryPreference.Electronic &&
|
||||
currentSettings.UnifiedOptInEmail != currentSettings.ENotificationsEmail)
|
||||
{
|
||||
_updateMemberEmail.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentSettings.UniversalOptIn == DeliveryPreference.Hold &&
|
||||
currentSettings.ENotifications == DeliveryPreference.Electronic)
|
||||
{
|
||||
_updateMemberToPrint.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentSettings.UniversalOptIn == DeliveryPreference.Microfiche &&
|
||||
currentSettings.ENotifications == DeliveryPreference.Electronic)
|
||||
{
|
||||
_updateMemberToPrint.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<XdiBatchFile> GetNonEmptyFiles(string pathPrefix = "")
|
||||
{
|
||||
var list = new List<XdiBatchFile>();
|
||||
if (_updateMemberEmail.HasRows())
|
||||
{
|
||||
_updateMemberEmail.FolderPrefix = pathPrefix;
|
||||
list.Add(_updateMemberEmail);
|
||||
}
|
||||
|
||||
if (_addMemberElectronic.HasRows())
|
||||
{
|
||||
_addMemberElectronic.FolderPrefix = pathPrefix;
|
||||
list.Add(_addMemberElectronic);
|
||||
}
|
||||
|
||||
if (_updateMemberToElectronic.HasRows())
|
||||
{
|
||||
_updateMemberToElectronic.FolderPrefix = pathPrefix;
|
||||
list.Add(_updateMemberToElectronic);
|
||||
}
|
||||
|
||||
if (_updateMemberToPrint.HasRows())
|
||||
{
|
||||
_updateMemberToPrint.FolderPrefix = pathPrefix;
|
||||
list.Add(_updateMemberToPrint);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using System.Text;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
public class XdiBatchFile
|
||||
{
|
||||
private const string Ext = "LMCU.txt";
|
||||
public XdiFileType Type { get; set; }
|
||||
public List<XdiBatchFileRow> Data { get; set; } = new List<XdiBatchFileRow>();
|
||||
public string FolderPrefix { get; set; } = "";
|
||||
|
||||
public string GetFileName()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case XdiFileType.AddMemberElectronic: return $"{FolderPrefix}Enrollment_AddElectronic_{Ext}";
|
||||
case XdiFileType.DeleteMember: return $"{FolderPrefix}Enrollment_Delete_{Ext}";
|
||||
case XdiFileType.UpdateMemberEmail: return $"{FolderPrefix}Enrollment_UpdateEmail_{Ext}";
|
||||
case XdiFileType.UpdateMemberToElectronic: return $"{FolderPrefix}Enrollment_UpdateToElectronic_{Ext}";
|
||||
case XdiFileType.UpdateMemberToPrint: return $"{FolderPrefix}Enrollment_UpdateToPrint_{Ext}";
|
||||
default: throw new Exception($"Unknown File Type in XDI BatchFile: {Type}");
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRow(string userId, string email)
|
||||
{
|
||||
var row = new XdiBatchFileRow()
|
||||
{
|
||||
UserId = $"{userId}",
|
||||
Email = email
|
||||
};
|
||||
|
||||
Data.Add(row);
|
||||
}
|
||||
|
||||
public IEnumerable<string> ConvertToDataRows()
|
||||
{
|
||||
return Data.Select(batchRow => batchRow.ConvertToRow(Type));
|
||||
}
|
||||
|
||||
public byte[] ConvertToDataFile()
|
||||
{
|
||||
var allRows = ConvertToDataRows();
|
||||
var file = string.Join("\n", allRows);
|
||||
return Encoding.UTF8.GetBytes(file);
|
||||
}
|
||||
|
||||
public bool HasRows()
|
||||
{
|
||||
return Data != null && Data.Any();
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
|
||||
public class XdiBatchFileRow
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string CellPhone { get; set; }
|
||||
|
||||
public string ConvertToRow(XdiFileType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case XdiFileType.UpdateMemberToPrint:
|
||||
case XdiFileType.DeleteMember: return UserId + "|";
|
||||
case XdiFileType.AddMemberElectronic:
|
||||
case XdiFileType.UpdateMemberEmail:
|
||||
case XdiFileType.UpdateMemberToElectronic: return UserId + "|" + Email + "|";
|
||||
default: throw new Exception($"Unknown File Type in XDIBatchFileRow: {type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
using LCU.Library.Internal.Logging.Models;
|
||||
using LCU.Library.Internal.Logging;
|
||||
using LCU.Library.Internal.ApiSecurity;
|
||||
using LCU.Library.Internal.LcuHttpClient;
|
||||
using LCU.Library.Internal.Status;
|
||||
using LCU.Library.Internal.Configuration;
|
||||
using LCU.Library.Internal.LcuMassTransit;
|
||||
using LCU.Library.Internal.Logging.Middleware;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Consumers;
|
||||
using LCU.API.Internal.MemberPreferencesApi.HostedServices;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Persistence;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Interfaces;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Models;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using Infrastructure.Services;
|
||||
using Microsoft.FeatureManagement;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using MassTransit;
|
||||
|
||||
|
||||
string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
|
||||
var builder = BuildBuilder(args);
|
||||
BuildServicesAndConfigurations(builder);
|
||||
BuildAppAndRun(builder);
|
||||
|
||||
WebApplicationBuilder BuildBuilder(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Configuration.AddJsonFile("/app/config/mapped-appsettings/primary.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-member-preferences-api-key.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-ftp-fingerprint.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-ftp-password.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-ftp-username.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-queue-password.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-queue-username.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-db-connection.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-environment-from-vault.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/member-preferences-api-seq-api-key.json", optional: true, reloadOnChange: true);
|
||||
builder.Host.UseSerilog();
|
||||
return builder;
|
||||
}
|
||||
|
||||
void BuildServicesAndConfigurations(WebApplicationBuilder builder)
|
||||
{
|
||||
var services = builder.Services;
|
||||
var configuration = builder.Configuration;
|
||||
var apiConfiguration = configuration.Bind<ApiConfiguration>(services, "Primary");
|
||||
configuration.Bind<XdiSftpApiConfiguration>(services);
|
||||
configuration.Bind<FtpApiConfiguration>(services);
|
||||
configuration.Bind<NotificationApiConfiguration>(services);
|
||||
configuration.Bind<CoreApiWrapperConfiguration>(services);
|
||||
configuration.Bind<DnaAuditProcessConfiguration>(services);
|
||||
|
||||
var loggerConfiguration = new LoggingConfiguration(apiConfiguration.AppName,
|
||||
apiConfiguration.SeqKey,
|
||||
apiConfiguration.SeqUrl);
|
||||
|
||||
var lcuLogging = new LcuLogging(loggerConfiguration);
|
||||
lcuLogging.UseLcuLogging();
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(MyAllowSpecificOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder.WithOrigins(
|
||||
apiConfiguration.CorsAllowedOrigins
|
||||
).AllowAnyHeader().AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddHttpClient();
|
||||
|
||||
var databaseSettings = configuration.Bind<SqlConnectionConfiguration>(services, "SqlConnectionConfiguration");
|
||||
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer
|
||||
(
|
||||
databaseSettings.ConnectionString,
|
||||
sql => sql.EnableRetryOnFailure(databaseSettings.MaxRetryCount, databaseSettings.MaxRetryDelay, null)
|
||||
);
|
||||
});
|
||||
|
||||
services.AddLCUStatusServicesWithApiHealthCheck(configuration);
|
||||
services.AddLCUHttpServices();
|
||||
services.AddControllers();
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{apiConfiguration.AppName}", Version = "v1" });
|
||||
});
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunHostedServices)
|
||||
{
|
||||
services.AddHostedService<HostedXdiBatchProcessService>();
|
||||
services.AddHostedService<HostedDnaDataAuditProcessService>();
|
||||
}
|
||||
|
||||
services.AddFeatureManagement(configuration.GetSection("Primary:FeatureGates"));
|
||||
|
||||
services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());
|
||||
services.AddScoped<IAuditableChanges>(provider => provider.GetService<ApplicationDbContext>());
|
||||
services.AddTransient<IDateTime, DateTimeService>();
|
||||
services.AddApiKeySecurity(configuration);
|
||||
|
||||
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, configuration);
|
||||
|
||||
var receiveEndpointConfigurations = new ReceiveEndpointConfigurations()
|
||||
{
|
||||
XdiBatchProcessEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "XdiBatchProcessEndpoint"),
|
||||
|
||||
XdiBatchConfirmEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "XdiBatchConfirmEndpoint"),
|
||||
|
||||
DnaAccountAuditEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "DnaAccountAuditEndpoint"),
|
||||
|
||||
DnaAgreementAuditEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "DnaAgreementAuditEndpoint"),
|
||||
|
||||
DnaOrganizationAuditEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "DnaOrganizationAuditEndpoint"),
|
||||
};
|
||||
|
||||
services.AddSingleton(receiveEndpointConfigurations);
|
||||
|
||||
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, apiConfiguration);
|
||||
AddMemberPreferencesApiServices(services);
|
||||
AddMemberPreferencesDaos(services);
|
||||
AddMemberPreferencesLib(ref services);
|
||||
}
|
||||
|
||||
void AddMassTransitServices(ref IServiceCollection services,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations,
|
||||
ApiConfiguration configuration)
|
||||
{
|
||||
services.AddMassTransit(x =>
|
||||
{
|
||||
x.AddConsumer<XdiBatchProcessConsumer>();
|
||||
x.AddConsumer<XdiSshResponseConsumer>();
|
||||
x.AddConsumer<AccountDnaFieldChangeConsumer>();
|
||||
x.AddConsumer<AgreementDnaFieldChangeConsumer>();
|
||||
x.AddConsumer<OrganizationDnaFieldChangeConsumer>();
|
||||
|
||||
x.UsingRabbitMq((context, cfg) =>
|
||||
{
|
||||
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
|
||||
{
|
||||
host.Username(connectionConfiguration.UserName);
|
||||
host.Password(connectionConfiguration.Password);
|
||||
});
|
||||
|
||||
if (configuration.FeatureFlags.RunXdiBatchProcessConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.XdiBatchProcessEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<XdiBatchProcessConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.XdiBatchProcessEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (configuration.FeatureFlags.RunXdiSshResponseConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.XdiBatchConfirmEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<XdiSshResponseConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.XdiBatchConfirmEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (configuration.FeatureFlags.RunAccountDnaFieldChangeConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DnaAccountAuditEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<AccountDnaFieldChangeConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.DnaAccountAuditEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (configuration.FeatureFlags.RunAgreementDnaFieldChangeConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DnaAgreementAuditEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<AgreementDnaFieldChangeConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.DnaAgreementAuditEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (configuration.FeatureFlags.RunOrganizationDnaFieldChangeConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DnaOrganizationAuditEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<OrganizationDnaFieldChangeConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.DnaOrganizationAuditEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
services.AddMassTransitHostedService();
|
||||
}
|
||||
|
||||
void AddMemberPreferencesApiServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IOptinService, OptinService>();
|
||||
services.AddScoped<IMemberEmailService, MemberEmailService>();
|
||||
services.AddScoped<IMemberPreferenceService, MemberPreferenceService>();
|
||||
services.AddScoped<IIntegrationService, IntegrationService>();
|
||||
|
||||
AddDnaAuditServices(services);
|
||||
AddXdiServices(services);
|
||||
AddEmailUndeliverableServices(services);
|
||||
AddQueueServices(services);
|
||||
AddMicroApiServices(services);
|
||||
}
|
||||
|
||||
void AddDnaAuditServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IDNADataAuditService, DNADataAuditService>();
|
||||
services.AddScoped<IDNADataAuditProcessService, DNADataAuditProcessService>();
|
||||
}
|
||||
|
||||
void AddXdiServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IXdiBatchService, XdiBatchService>();
|
||||
services.AddScoped<IXdiBatchProcessService, XdiBatchProcessService>();
|
||||
}
|
||||
|
||||
void AddEmailUndeliverableServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<EStatementsSixtyDaysUndeliverableEmailPolicy>();
|
||||
services.AddScoped<UnifiedSixtyDaysUndeliverableEmailPolicy>();
|
||||
services.AddTransient<IEnumerable<IEmailFailurePolicy>>(p => new IEmailFailurePolicy[]
|
||||
{
|
||||
p.GetRequiredService<EStatementsSixtyDaysUndeliverableEmailPolicy>(),
|
||||
p.GetRequiredService<UnifiedSixtyDaysUndeliverableEmailPolicy>()
|
||||
});
|
||||
}
|
||||
|
||||
void AddQueueServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IQueueDnaAccountAuditService, QueueDnaAccountAuditService>();
|
||||
services.AddScoped<IQueueDnaOrganizationAuditService, QueueDnaOrganizationService>();
|
||||
services.AddScoped<IQueueDnaAgreementAuditService, QueueDnaAgreementAuditService>();
|
||||
services.AddScoped<IQueueXdiBatchService, QueueXdiBatchService>();
|
||||
}
|
||||
|
||||
void AddMicroApiServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<ICoreApiWrapperService, CoreApiWrapperService>();
|
||||
services.AddScoped<IFtpApiService, FtpApiService>();
|
||||
services.AddScoped<INotificationService, NotificationService>();
|
||||
}
|
||||
|
||||
void AddMemberPreferencesDaos(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<INotificationApiDao, NotificationApiDao>();
|
||||
services.AddScoped<IFtpApiDao, FtpApiDao>();
|
||||
services.AddScoped<ICoreApiWrapperDao, CoreApiWrapperDao>();
|
||||
}
|
||||
|
||||
void AddMemberPreferencesLib(ref IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
||||
services.AddScoped<IUnifiedOptInRepository, UnifiedOptInRepository>();
|
||||
services.AddScoped<IMemberPreferenceRepository, MemberPreferenceRepository>();
|
||||
services.AddScoped<IMemberPreferences, MemberPreferenceRepository>();
|
||||
services.AddScoped<IXdiBatchItemsRepository, XdiBatchItemsRepository>();
|
||||
services.AddScoped<IDnaAuditProcessRepository, DnaAuditProcessRepository>();
|
||||
}
|
||||
|
||||
void BuildAppAndRun(WebApplicationBuilder builder)
|
||||
{
|
||||
var app = builder.Build();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseSwagger(c =>
|
||||
{
|
||||
c.PreSerializeFilters.Add((swaggerDoc, request) =>
|
||||
{
|
||||
const string prefixHeader = "X-Forwarded-Prefix";
|
||||
if (!request.Headers.ContainsKey(prefixHeader)) return;
|
||||
|
||||
var serverUrl = request.Headers[prefixHeader];
|
||||
swaggerDoc.Servers = new List<OpenApiServer>()
|
||||
{
|
||||
new() { Description = serverUrl, Url = serverUrl }
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.RoutePrefix = "swagger";
|
||||
c.SwaggerEndpoint("v1/swagger.json", "LCU.API.Internal.MemberPreferencesApi v1");
|
||||
});
|
||||
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
app.UseSerilogRequestLogging(options =>
|
||||
{
|
||||
options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest;
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseCors(MyAllowSpecificOrigins);
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
app.Run();
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Interfaces;
|
||||
|
||||
namespace Infrastructure.Services;
|
||||
|
||||
public class DateTimeService : IDateTime
|
||||
{
|
||||
public DateTime Now => DateTime.Now;
|
||||
|
||||
public DateTime UTCNow => DateTime.UtcNow;
|
||||
|
||||
public DateTime? CSTWindowsNow
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
|
||||
return TimeZoneInfo.ConvertTimeFromUtc(UTCNow, easternZone);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? CSTLinuxNow
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("America/Chicago");
|
||||
return TimeZoneInfo.ConvertTimeFromUtc(UTCNow, easternZone);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime ConvertDateTimeFromCSTToUTCLinux(string dateTimeString)
|
||||
{
|
||||
var date = DateTime.Parse(dateTimeString);
|
||||
return TimeZoneInfo.ConvertTime(date, TimeZoneInfo.FindSystemTimeZoneById("America/Chicago"), TimeZoneInfo.Utc);
|
||||
}
|
||||
|
||||
public DateTime ConvertDateTimeFromCSTToUTCWindows(string dateTimeString)
|
||||
{
|
||||
var date = DateTime.Parse(dateTimeString);
|
||||
return TimeZoneInfo.ConvertTime(date, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"), TimeZoneInfo.Utc);
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Interfaces;
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
|
||||
public class DNADataAuditProcessService : IDNADataAuditProcessService
|
||||
{
|
||||
private readonly IDateTime _dateTime;
|
||||
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
||||
private readonly IDnaAuditProcessRepository _dnaAuditProcessRepository;
|
||||
private readonly DnaAuditProcessConfiguration _dnaAuditProcessConfig;
|
||||
private readonly IQueueDnaAccountAuditService _queueDnaAccountAuditService;
|
||||
private readonly IQueueDnaAgreementAuditService _queueDnaAgreementAuditService;
|
||||
private readonly IQueueDnaOrganizationAuditService _queueDnaOrganizationAuditService;
|
||||
|
||||
public DNADataAuditProcessService(IQueueDnaAccountAuditService queueDnaAccountAuditService,
|
||||
IQueueDnaAgreementAuditService queueDnaAgreementAuditService,
|
||||
IQueueDnaOrganizationAuditService queueDnaOrganizationAuditService,
|
||||
ICoreApiWrapperService coreApiWrapperService, IDateTime dateTime,
|
||||
IDnaAuditProcessRepository dnaAuditProcessRepository, DnaAuditProcessConfiguration dnaAuditProcessConfig)
|
||||
{
|
||||
_queueDnaAccountAuditService = queueDnaAccountAuditService;
|
||||
_queueDnaAgreementAuditService = queueDnaAgreementAuditService;
|
||||
_queueDnaOrganizationAuditService = queueDnaOrganizationAuditService;
|
||||
_coreApiWrapperService = coreApiWrapperService;
|
||||
_dateTime = dateTime;
|
||||
_dnaAuditProcessRepository = dnaAuditProcessRepository;
|
||||
_dnaAuditProcessConfig = dnaAuditProcessConfig;
|
||||
}
|
||||
|
||||
public async Task RunDataAuditProcesses()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnaProcesses = await _dnaAuditProcessRepository.GetAllDnaAuditProcesses();
|
||||
|
||||
foreach (var dnaProcess in dnaProcesses)
|
||||
{
|
||||
var timeToSearchFrom = dnaProcess.LastUpdated.AddMinutes(_dnaAuditProcessConfig.LookBackMinutes);
|
||||
|
||||
switch (dnaProcess.DnaProcessType)
|
||||
{
|
||||
case DnaAuditProcessType.DNAOrganization:
|
||||
await AuditDNAOrganizationForTimePeriod(timeToSearchFrom, dnaProcess);
|
||||
break;
|
||||
case DnaAuditProcessType.DNAAgreement:
|
||||
await AuditDNAAgreementForTimePeriod(timeToSearchFrom, dnaProcess);
|
||||
break;
|
||||
case DnaAuditProcessType.DNAAccounts:
|
||||
await AuditDNAAccountsForTimePeriod(timeToSearchFrom, dnaProcess);
|
||||
break;
|
||||
default:
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error($"DnaAuditProcessType not found for ProcessId: {dnaProcess.ProcessId}. ProcessType: {dnaProcess.DnaProcessType}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group), Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(ex, "Failed to Queue Last 5 Minutes of MemberPreference DNA DataAudit Activity");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AuditDNAOrganizationForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnaOrganizationAuditRecords = await _coreApiWrapperService.GetAuditOrganizationFromDateLastMaintained(timeToSearchFrom);
|
||||
var organizationAuditRecords = dnaOrganizationAuditRecords.ToList();
|
||||
await _queueDnaOrganizationAuditService.QueueDataAuditForOrganizations(organizationAuditRecords, dnaProcess.ConsecutiveFailures);
|
||||
|
||||
Log.Information($"Queued {organizationAuditRecords.Count} DataAudit Organization Changes Since Last DNADataAuditProducerService Run.");
|
||||
dnaProcess = HandleDnaAuditProcessSuccess(dnaProcess);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
dnaProcess = HandleDnaAuditProcessException(dnaProcess, ex);
|
||||
}
|
||||
await _dnaAuditProcessRepository.Update(dnaProcess);
|
||||
}
|
||||
|
||||
public async Task AuditDNAAgreementForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnaAgreementAuditRecords = await _coreApiWrapperService.GetAuditAgreementFromDateLastMaintained(timeToSearchFrom);
|
||||
var agreementAuditRecords = dnaAgreementAuditRecords.ToList();
|
||||
await _queueDnaAgreementAuditService.QueueDataAuditForAgreements(agreementAuditRecords, dnaProcess.ConsecutiveFailures);
|
||||
|
||||
Log.Information($"Queued {agreementAuditRecords.Count} DataAudit Agreement Changes Since Last DNADataAuditProducerService Run.");
|
||||
dnaProcess = HandleDnaAuditProcessSuccess(dnaProcess);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
dnaProcess = HandleDnaAuditProcessException(dnaProcess, ex);
|
||||
}
|
||||
|
||||
await _dnaAuditProcessRepository.Update(dnaProcess);
|
||||
}
|
||||
|
||||
public async Task AuditDNAAccountsForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnaAccountAuditRecords = await _coreApiWrapperService.GetAuditAccountsFromDateLastMaintained(timeToSearchFrom);
|
||||
var accountAuditRecords = dnaAccountAuditRecords.ToList();
|
||||
await _queueDnaAccountAuditService.QueueDataAuditForAccounts(accountAuditRecords, dnaProcess.ConsecutiveFailures);
|
||||
|
||||
Log.Information($"Queued {accountAuditRecords.Count} DataAudit Account Changes Since Last DNADataAuditProducerService Run.");
|
||||
dnaProcess = HandleDnaAuditProcessSuccess(dnaProcess);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
dnaProcess = HandleDnaAuditProcessException(dnaProcess, ex);
|
||||
}
|
||||
|
||||
await _dnaAuditProcessRepository.Update(dnaProcess);
|
||||
}
|
||||
|
||||
public DnaAuditProcess HandleDnaAuditProcessException(DnaAuditProcess process, Exception ex)
|
||||
{
|
||||
process.ConsecutiveFailures++;
|
||||
|
||||
if (process.ConsecutiveFailures >= _dnaAuditProcessConfig.NumberOfAllowedConsecutiveFailures)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error($"DnaAuditProcess for {process.DnaProcessType} has failed {process.ConsecutiveFailures} consecutive times. " +
|
||||
$"Last succesful runtime: {process.LastUpdated} CST. " +
|
||||
$"This process needs to checked on to determine why failure is occuring.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"Exception and Failure occured for DnaAuditProcess: {process.DnaProcessType}. ConsecutiveFailures: {process.ConsecutiveFailures}. " +
|
||||
$"Last succesful runtime: {process.LastUpdated} CST. Exception: {ex}");
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
public DnaAuditProcess HandleDnaAuditProcessSuccess(DnaAuditProcess process)
|
||||
{
|
||||
var utcTime = _dateTime.UTCNow;
|
||||
var easternZone = TimeZoneConverter.TZConvert.GetTimeZoneInfo("America/Chicago");
|
||||
var easternTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, easternZone);
|
||||
process.LastUpdated = easternTime;
|
||||
process.ConsecutiveFailures = 0;
|
||||
return process;
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
|
||||
public class DNADataAuditService : IDNADataAuditService
|
||||
{
|
||||
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
||||
private readonly IOptinService _optinService;
|
||||
|
||||
private const string MemberPreferencePrint = "PRNT";
|
||||
private const string MemberPreferenceElectronic = "WWW";
|
||||
|
||||
public DNADataAuditService(ICoreApiWrapperService coreApiWrapperService, IOptinService optinService)
|
||||
{
|
||||
_optinService = optinService;
|
||||
_coreApiWrapperService = coreApiWrapperService;
|
||||
}
|
||||
|
||||
public async Task HandleAccountAuditCheck(DnaFieldChangeRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var accountNumber = request.DnaFieldIdInformation;
|
||||
var account = await _coreApiWrapperService.GetAgreementAccountByAccountId(accountNumber);
|
||||
|
||||
if (account == null)
|
||||
{
|
||||
Log.Information($"During audit process account with ID: {accountNumber} could not be found, and will not be processed.");
|
||||
return;
|
||||
}
|
||||
|
||||
await UpdateAccountDeliveryMethodIfNotEqualToMemberPreference(account);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex,
|
||||
$"Failed to process DNA Audit for member preferences Account.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleAgreementAuditCheck(DnaFieldChangeRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var agreementNumber = request.DnaFieldIdInformation;
|
||||
var agreement = await _coreApiWrapperService.GetAgreementByAgreementId(agreementNumber);
|
||||
|
||||
if (agreement == null)
|
||||
{
|
||||
Log.Information($"During audit process agreement with ID: {agreementNumber} could not be found, and will not be processed.");
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<AgreementAccount> agreementAccounts;
|
||||
|
||||
if (agreement.ByOrgNbr != 0)
|
||||
{
|
||||
agreementAccounts = await _coreApiWrapperService.GetAgreementAccountsByOrganizationId(agreement.ByOrgNbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
agreementAccounts = await _coreApiWrapperService.GetAgreementAccountsByUserId(agreement.UserId);
|
||||
agreementAccounts = agreementAccounts.Where(account => account.TaxReportForPersonNumber != null && account.AccountOwner.AgreementNumber == agreement.AgreementNumber);
|
||||
}
|
||||
|
||||
foreach (var agreementAccount in agreementAccounts)
|
||||
{
|
||||
await UpdateAccountDeliveryMethodIfNotEqualToMemberPreference(agreementAccount);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex,
|
||||
$"Failed to process DNA Audit for member preferences Agreement.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleOrganizationAuditCheck(DnaFieldChangeRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var organizationId = request.DnaFieldIdInformation;
|
||||
var organizationAccounts = await _coreApiWrapperService.GetAgreementAccountsByOrganizationId(organizationId);
|
||||
|
||||
if (organizationAccounts == null)
|
||||
{
|
||||
Log.Information($"During audit process organization with ID: {organizationId} could not be found, and will not be processed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var account in organizationAccounts)
|
||||
{
|
||||
await UpdateAccountDeliveryMethodIfNotEqualToMemberPreference(account);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex,
|
||||
$"Failed to process DNA Audit for member preferences Organization.");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateAccountDeliveryMethodIfNotEqualToMemberPreference(AgreementAccount account)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (account.AccountOwner?.UserId == null)
|
||||
{
|
||||
await _coreApiWrapperService.UpdateAgreementAccountsDeliveryMethod(new List<long> { account.AccountNumber }, "PRNT", "None Found During Audit");
|
||||
return;
|
||||
}
|
||||
|
||||
var currentAccountDeliveryMethod = account.OvrDeliveryMethCD;
|
||||
|
||||
var memberOptinSettings = await _optinService.GetMemberOptInSettings(account.AccountOwner.UserId);
|
||||
var memberPreferenceDeliveryMethod = DetermineMemberPreference(memberOptinSettings);
|
||||
|
||||
if (!string.Equals(currentAccountDeliveryMethod, memberPreferenceDeliveryMethod, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
await _coreApiWrapperService.UpdateAgreementAccountsDeliveryMethod(new List<long> { account.AccountNumber }, memberPreferenceDeliveryMethod, account.AccountOwner.UserId);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to UpdateAccountDeliveryMethodIfNotEqualToMemberPreference for account number: {account.AccountNumber}");
|
||||
}
|
||||
}
|
||||
|
||||
private string DetermineMemberPreference(MemberOptInSettings optinSettings)
|
||||
{
|
||||
if (optinSettings == null)
|
||||
{
|
||||
return MemberPreferencePrint;
|
||||
}
|
||||
|
||||
if (optinSettings.IsUnifiedElectronicEnrolled())
|
||||
{
|
||||
return MemberPreferenceElectronic;
|
||||
}
|
||||
|
||||
if (optinSettings.IsUnifiedPaperEnrolled())
|
||||
{
|
||||
return MemberPreferencePrint;
|
||||
}
|
||||
|
||||
if (string.Equals(optinSettings.EStatements, "Paper", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return MemberPreferencePrint;
|
||||
}
|
||||
|
||||
if (string.Equals(optinSettings.EStatements, "Electronic", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return MemberPreferenceElectronic;
|
||||
}
|
||||
|
||||
return MemberPreferencePrint;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
|
||||
public interface IDNADataAuditProcessService
|
||||
{
|
||||
Task RunDataAuditProcesses();
|
||||
Task AuditDNAOrganizationForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess);
|
||||
Task AuditDNAAgreementForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess);
|
||||
Task AuditDNAAccountsForTimePeriod(DateTime timeToSearchFrom, DnaAuditProcess dnaProcess);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
|
||||
public interface IDNADataAuditService
|
||||
{
|
||||
Task HandleAccountAuditCheck(DnaFieldChangeRequest dnaFieldChange);
|
||||
Task HandleAgreementAuditCheck(DnaFieldChangeRequest dnaFieldChange);
|
||||
Task HandleOrganizationAuditCheck(DnaFieldChangeRequest dnaFieldChange);
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.DnaAuditServices;
|
||||
using NCrontab;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.HostedServices
|
||||
{
|
||||
public class HostedDnaDataAuditProcessService : BackgroundService
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private CancellationToken _cancellationToken;
|
||||
private ApiConfiguration _memberPreferencesConfig;
|
||||
private readonly CrontabSchedule _cleanUpJobSchedule;
|
||||
private DateTime _nextScheduleRun;
|
||||
|
||||
public HostedDnaDataAuditProcessService(ApiConfiguration appConfig,
|
||||
IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
_memberPreferencesConfig = appConfig;
|
||||
_cleanUpJobSchedule = CrontabSchedule.Parse(_memberPreferencesConfig.DnaDataAuditProcessCronSchedule);
|
||||
_nextScheduleRun = _cleanUpJobSchedule.GetNextOccurrence(DateTime.Now);
|
||||
_cancellationToken = new CancellationToken();
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Log.Information("Hosted DNADataAuditProcessService is starting, for DNA Member Preferences Audit.");
|
||||
_cancellationToken = cancellationToken;
|
||||
try
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (DateTime.Now > _nextScheduleRun)
|
||||
{
|
||||
using (var scope = _scopeFactory.CreateScope())
|
||||
{
|
||||
await scope.ServiceProvider.GetRequiredService<IDNADataAuditProcessService>().RunDataAuditProcesses();
|
||||
}
|
||||
}
|
||||
await Task.Delay(UntilNextExecution(), cancellationToken);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException ex) when (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
Log.Information(ex, "Hosted DnaDataAuditProcessService was shut down normally.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error in main thread for DnaDataAuditProcessService");
|
||||
}
|
||||
|
||||
Log.Information("Hosted DnaDataAuditProcessService is stopping.");
|
||||
}
|
||||
|
||||
private int UntilNextExecution() => Math.Max(0, (int)_nextScheduleRun.Subtract(DateTime.Now).TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using NCrontab;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.HostedServices;
|
||||
|
||||
public class HostedXdiBatchProcessService : BackgroundService
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private CancellationToken _cancellationToken;
|
||||
private ApiConfiguration _apiConfiguration;
|
||||
private XdiSftpApiConfiguration _xdiSftpApiConfiguration;
|
||||
private readonly CrontabSchedule _cleanUpJobSchedule;
|
||||
private DateTime _nextScheduleRun;
|
||||
|
||||
public HostedXdiBatchProcessService(ApiConfiguration apiConfiguration, XdiSftpApiConfiguration xdiSftpApiConfiguration, IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
_apiConfiguration = apiConfiguration;
|
||||
_xdiSftpApiConfiguration = xdiSftpApiConfiguration;
|
||||
_cleanUpJobSchedule = CrontabSchedule.Parse(_apiConfiguration.XdiBatchProcessCronSchedule);
|
||||
_nextScheduleRun = _cleanUpJobSchedule.GetNextOccurrence(DateTime.Now);
|
||||
_cancellationToken = new CancellationToken();
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Log.Information("Hosted XDI Batch Service is starting");
|
||||
_cancellationToken = cancellationToken;
|
||||
try
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (DateTime.Now > _nextScheduleRun)
|
||||
{
|
||||
using (var scope = _scopeFactory.CreateScope())
|
||||
{
|
||||
await scope.ServiceProvider.GetRequiredService<IXdiBatchProcessService>().RunXdiBatchProcess(_xdiSftpApiConfiguration.SftpRootBasePath);
|
||||
}
|
||||
_nextScheduleRun = _cleanUpJobSchedule.GetNextOccurrence(DateTime.Now);
|
||||
}
|
||||
await Task.Delay(UntilNextExecution(), cancellationToken);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException ex) when (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
Log.Information(ex, "Hosted XdiBatchService was shut down normally");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error in main thread for XdiBatchService");
|
||||
}
|
||||
|
||||
Log.Information("Hosted XdiBatchService is stopping");
|
||||
}
|
||||
|
||||
private int UntilNextExecution() => Math.Max(0, (int)_nextScheduleRun.Subtract(DateTime.Now).TotalMilliseconds);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Interfaces;
|
||||
|
||||
public interface IDateTime
|
||||
{
|
||||
DateTime Now { get; }
|
||||
DateTime UTCNow { get; }
|
||||
DateTime? CSTLinuxNow { get; }
|
||||
DateTime? CSTWindowsNow { get; }
|
||||
DateTime ConvertDateTimeFromCSTToUTCWindows(string dateTimeString);
|
||||
DateTime ConvertDateTimeFromCSTToUTCLinux(string dateTimeString);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public interface IIntegrationService
|
||||
{
|
||||
Task NotifyListeners(MemberOptInSettings request);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public interface IMemberEmailService
|
||||
{
|
||||
Task<bool> EmailSucceededToSend(string userId, string email);
|
||||
Task<bool> EmailFailedToSend(string userId, string email, bool enablePolicy);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public interface IMemberPreferenceService
|
||||
{
|
||||
Task<IReadOnlyCollection<MemberPreference>> GetMemberPreferencesAsync(string userId);
|
||||
IReadOnlyCollection<string> GetAvailableTypes();
|
||||
Task<MemberOptInSettings> SaveMemberPreferenceAsync(MemberPreferenceRequest preference);
|
||||
Task<MemberOptInSettings> SaveMemberPreferencesAsync(List<MemberPreferenceRequest> preferences);
|
||||
Task<MemberOptInSettings> SaveMemberPreferenceDefaultAsync(MemberPreferenceRequest preferences, string operatorId, UserType userType, DateTime dateAdded);
|
||||
Task UpdateMemberOptinAsync(MemberOptinRequest optinRequest);
|
||||
Task UpdateAgreementDeliveryMethodCode(string userId, string deliveryMethod);
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.DataTransfer;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public interface IOptinService
|
||||
{
|
||||
Task<MemberOptInSettings> GetMemberOptInSettings(string userId);
|
||||
Task<MemberOptInSettings> GetMemberOptInSettingsOrCreateDefaultSetting(string userId);
|
||||
Task<IReadOnlyCollection<MemberOptInAgreementInformation>> GetMemberOptInAgreementInformationByAccountId(long accountId);
|
||||
Task<MemberOptInAgreementInformation> GetMemberOptInAgreementInformationForUser(string userId);
|
||||
Task<IReadOnlyCollection<MemberOptInInformation>> TransformMemberOptInSettingsForClient(List<MemberOptInSettings> memberOptInSettingsList);
|
||||
Task<MemberOptInInformation> TransformMemberOptInSettingsForClient(MemberOptInSettings memberOptInSettings);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public class IntegrationService : IIntegrationService
|
||||
{
|
||||
private readonly IXdiBatchService _xdiBatchItemService;
|
||||
|
||||
public IntegrationService(IXdiBatchService xdiBatchItemService)
|
||||
{
|
||||
_xdiBatchItemService = xdiBatchItemService;
|
||||
}
|
||||
|
||||
public async Task NotifyListeners(MemberOptInSettings request)
|
||||
{
|
||||
await NotifyXDI(request);
|
||||
}
|
||||
|
||||
private async Task NotifyXDI(MemberOptInSettings request)
|
||||
{
|
||||
var newItem = new XdiBatchItem()
|
||||
{
|
||||
UserId = request.UserId,
|
||||
Created = DateTime.Now,
|
||||
BatchState = BatchState.New,
|
||||
LastUpdated = DateTime.Now
|
||||
};
|
||||
await _xdiBatchItemService.AddXdiBatchItem(newItem);
|
||||
}
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models.EmailPolicies;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services
|
||||
{
|
||||
public class MemberEmailService : IMemberEmailService
|
||||
{
|
||||
private readonly IEnumerable<IEmailFailurePolicy> _failurePolicies;
|
||||
private readonly IUnifiedOptInRepository _unifiedOptInRepository;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IMemberPreferenceService _memberPreferenceService;
|
||||
private readonly IIntegrationService _integrationService;
|
||||
public MemberEmailService(IUnifiedOptInRepository unifiedOptInRepository, IUnitOfWork unitOfWork, IEnumerable<IEmailFailurePolicy> failurePolicies,
|
||||
IMemberPreferenceService memberPreferenceService, IIntegrationService integrationService)
|
||||
{
|
||||
_unifiedOptInRepository = unifiedOptInRepository;
|
||||
_unitOfWork = unitOfWork;
|
||||
_failurePolicies = failurePolicies;
|
||||
_memberPreferenceService = memberPreferenceService;
|
||||
_integrationService = integrationService;
|
||||
}
|
||||
|
||||
public async Task<bool> EmailSucceededToSend(string userId, string email)
|
||||
{
|
||||
var userOptin = await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
if (userOptin is null) return false;
|
||||
|
||||
var updated = false;
|
||||
if (EmailMatches(email, userOptin.UnifiedOptInEmail))
|
||||
{
|
||||
UnifiedOptInEmailSucceededToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (EmailMatches(email, userOptin.ENotificationsEmail))
|
||||
{
|
||||
ENotificationsEmailSucceededToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (EmailMatches(email, userOptin.EStatementsEmail))
|
||||
{
|
||||
EStatementsEmailSucceededToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
public async Task<bool> EmailFailedToSend(string userId, string email, bool enablePolicy)
|
||||
{
|
||||
var userOptin = await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
if (userOptin == null) return false;
|
||||
|
||||
var updated = false;
|
||||
var isBounceBack = false;
|
||||
if (userOptin.HasAnyUnifiedPreference())
|
||||
{
|
||||
if (EmailMatches(email, userOptin.UnifiedOptInEmail))
|
||||
{
|
||||
UnifiedOptInEmailFailedToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EmailMatches(email, userOptin.ENotificationsEmail))
|
||||
{
|
||||
ENotificationsEmailFailedToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (EmailMatches(email, userOptin.EStatementsEmail))
|
||||
{
|
||||
EStatementsEmailFailedToSend(userOptin);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var policy in _failurePolicies)
|
||||
{
|
||||
if (await policy.Apply(userOptin, enablePolicy))
|
||||
{
|
||||
updated = true;
|
||||
isBounceBack = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
await _unitOfWork.CompleteAsync();
|
||||
}
|
||||
|
||||
if (isBounceBack)
|
||||
{
|
||||
await _memberPreferenceService.UpdateAgreementDeliveryMethodCode(userId, "PRNT");
|
||||
await _integrationService.NotifyListeners(userOptin);
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
private static bool EmailMatches(string email, string otherEmail)
|
||||
{
|
||||
if (email is null) return otherEmail is null;
|
||||
|
||||
return email.Equals(otherEmail, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static void UnifiedOptInEmailSucceededToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
UnifiedOptInEmailAttempted(userOptin);
|
||||
userOptin.UnifiedOptInEmailStatus = EmailStatus.DeliveredSuccessfully;
|
||||
userOptin.UnifiedOptInEmailFirstSent = null;
|
||||
userOptin.UnifiedOptInEmailStatusCount = 0;
|
||||
}
|
||||
|
||||
private static void UnifiedOptInEmailFailedToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
UnifiedOptInEmailAttempted(userOptin);
|
||||
userOptin.UnifiedOptInEmailStatus = EmailStatus.FailingDelivery;
|
||||
userOptin.UnifiedOptInEmailFirstSent ??= DateTime.Now;
|
||||
userOptin.UnifiedOptInEmailStatusCount++;
|
||||
}
|
||||
|
||||
private static void UnifiedOptInEmailAttempted(MemberOptInSettings userOptin)
|
||||
{
|
||||
userOptin.UnifiedOptInEmailLastSent = DateTime.Now;
|
||||
}
|
||||
|
||||
private static void EStatementsEmailSucceededToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
EStatementsEmailAttempted(userOptin);
|
||||
userOptin.EStatementsEmailStatus = EmailStatus.DeliveredSuccessfully;
|
||||
userOptin.EStatementsEmailFirstSent = null;
|
||||
userOptin.EStatementsEmailStatusCount = 0;
|
||||
}
|
||||
|
||||
private static void EStatementsEmailFailedToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
EStatementsEmailAttempted(userOptin);
|
||||
userOptin.EStatementsEmailStatus = EmailStatus.FailingDelivery;
|
||||
userOptin.EStatementsEmailFirstSent ??= DateTime.Now;
|
||||
userOptin.EStatementsEmailStatusCount++;
|
||||
}
|
||||
|
||||
private static void EStatementsEmailAttempted(MemberOptInSettings userOptin)
|
||||
{
|
||||
userOptin.EStatementsEmailLastSent = DateTime.Now;
|
||||
}
|
||||
|
||||
private static void ENotificationsEmailSucceededToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
ENotificationsEmailAttempted(userOptin);
|
||||
userOptin.ENotificationsEmailStatus = EmailStatus.DeliveredSuccessfully;
|
||||
userOptin.ENotificationsEmailFirstSent = null;
|
||||
userOptin.ENotificationsEmailStatusCount = 0;
|
||||
}
|
||||
|
||||
private static void ENotificationsEmailFailedToSend(MemberOptInSettings userOptin)
|
||||
{
|
||||
ENotificationsEmailAttempted(userOptin);
|
||||
userOptin.ENotificationsEmailStatus = EmailStatus.FailingDelivery;
|
||||
userOptin.ENotificationsEmailFirstSent ??= DateTime.Now;
|
||||
userOptin.ENotificationsEmailStatusCount++;
|
||||
}
|
||||
|
||||
private static void ENotificationsEmailAttempted(MemberOptInSettings userOptin)
|
||||
{
|
||||
userOptin.ENotificationsEmailLastSent = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public class MemberPreferenceService : IMemberPreferenceService
|
||||
{
|
||||
private readonly IMemberPreferenceRepository _memberPreferenceRepository;
|
||||
private readonly IUnifiedOptInRepository _unifiedOptInRepository;
|
||||
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly IIntegrationService _integrationService;
|
||||
private readonly IXdiBatchService _xdiBatchItemService;
|
||||
private List<long> _accountNumbers;
|
||||
|
||||
public MemberPreferenceService(IMemberPreferenceRepository memberPreferenceRepository, IUnitOfWork unitOfWork,
|
||||
IUnifiedOptInRepository unifiedOptInRepository, INotificationService notificationService,
|
||||
IIntegrationService integrationService, IXdiBatchService xdiBatchItemService, ICoreApiWrapperService coreApiWrapperService)
|
||||
{
|
||||
_memberPreferenceRepository = memberPreferenceRepository;
|
||||
_unitOfWork = unitOfWork;
|
||||
_unifiedOptInRepository = unifiedOptInRepository;
|
||||
_notificationService = notificationService;
|
||||
_integrationService = integrationService;
|
||||
_xdiBatchItemService = xdiBatchItemService;
|
||||
_coreApiWrapperService = coreApiWrapperService;
|
||||
}
|
||||
|
||||
public async Task<MemberOptInSettings> SaveMemberPreferenceAsync(MemberPreferenceRequest preference)
|
||||
{
|
||||
return await SaveMemberPreferencesAsync(new List<MemberPreferenceRequest>()
|
||||
{
|
||||
preference
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<MemberOptInSettings> SaveMemberPreferencesAsync(List<MemberPreferenceRequest> preferences)
|
||||
{
|
||||
if (preferences == null || !preferences.Any())
|
||||
{
|
||||
throw new ArgumentException("No preferences passed to SaveMemberPreferencesAsync");
|
||||
}
|
||||
|
||||
var userId = preferences.FirstOrDefault()?.UserId;
|
||||
|
||||
if (await _xdiBatchItemService.DoesMemberHavePendingXdiChange(userId))
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
var settings = await _unifiedOptInRepository.GetOrCreateMemberOptinSettings(userId);
|
||||
|
||||
foreach (var preference in preferences)
|
||||
{
|
||||
var memberPreference = new MemberPreference()
|
||||
{
|
||||
Preference = preference.Preference,
|
||||
UserId = preference.UserId,
|
||||
Value = preference.Value,
|
||||
LegalReference = preference.LegalReference
|
||||
};
|
||||
|
||||
await _memberPreferenceRepository.SaveMemberPreferenceAsync(memberPreference);
|
||||
settings.Apply(memberPreference);
|
||||
}
|
||||
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
if (preferences.Any(preference => preference.Preference == PreferenceType.UnifiedOptIn && string.Equals(preference.Value, "Paper", StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
await UpdateAgreementDeliveryMethodCode(userId, "PRNT");
|
||||
}
|
||||
else if (preferences.Any(preference => preference.Preference == PreferenceType.UnifiedOptIn && string.Equals(preference.Value, "Electronic", StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
await UpdateAgreementDeliveryMethodCode(userId, "WWW");
|
||||
}
|
||||
|
||||
return await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
}
|
||||
|
||||
public async Task<MemberOptInSettings> SaveMemberPreferenceDefaultAsync(MemberPreferenceRequest preference, string operatorId, UserType userType, DateTime dateAdded)
|
||||
{
|
||||
if (preference == null)
|
||||
{
|
||||
throw new ArgumentException("No preferences passed to SaveMemberPreferencesAsync");
|
||||
}
|
||||
|
||||
var userId = preference.UserId;
|
||||
var settings = await _unifiedOptInRepository.GetOrCreateMemberOptinSettings(userId);
|
||||
|
||||
if (!IsExternalUpdateNecessary(settings, preference))
|
||||
{
|
||||
var memberPreference = new MemberPreference()
|
||||
{
|
||||
Preference = preference.Preference,
|
||||
UserId = preference.UserId,
|
||||
Value = preference.Value,
|
||||
LegalReference = preference.LegalReference
|
||||
};
|
||||
|
||||
await _memberPreferenceRepository.SaveMemberPreferenceAsync(memberPreference);
|
||||
settings.Apply(memberPreference);
|
||||
await _unitOfWork.CompleteAsync(operatorId, dateAdded, userType);
|
||||
}
|
||||
|
||||
return await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
}
|
||||
|
||||
public bool IsExternalUpdateNecessary(MemberOptInSettings settings, MemberPreferenceRequest request)
|
||||
{
|
||||
switch (request.Preference)
|
||||
{
|
||||
case PreferenceType.EStatementsEmail:
|
||||
return settings.EStatementsEmail != request.Value;
|
||||
|
||||
case PreferenceType.EStatements:
|
||||
return settings.EStatements != request.Value;
|
||||
|
||||
case PreferenceType.ENotification:
|
||||
return settings.ENotifications != request.Value;
|
||||
|
||||
case PreferenceType.ENotificationsEmail:
|
||||
return settings.ENotificationsEmail != request.Value;
|
||||
|
||||
case PreferenceType.UnifiedOptInEmail:
|
||||
return settings.UnifiedOptInEmail != request.Value && settings.HasAnyUnifiedPreference();
|
||||
|
||||
case PreferenceType.UnifiedOptIn:
|
||||
return settings.UniversalOptIn != request.Value && settings.HasAnyUnifiedPreference();
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateAgreementDeliveryMethodCode(string userId, string deliveryMethod)
|
||||
{
|
||||
try
|
||||
{
|
||||
var agreement = await _coreApiWrapperService.GetAgreementByUserId(userId);
|
||||
|
||||
if (agreement == null)
|
||||
{
|
||||
await _notificationService.SendDNAAgreementErrorNotification(userId, deliveryMethod);
|
||||
return;
|
||||
}
|
||||
if (agreement.ByOrgNbr != 0)
|
||||
{
|
||||
await UpdateAgreementAccountsForOrganization(userId, deliveryMethod, agreement);
|
||||
}
|
||||
else
|
||||
{
|
||||
await UpdateAgreementAccountsForPerson(userId, deliveryMethod, agreement);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to Update Agreement Accounts for userId: {userId} to DeliveryMethod: {deliveryMethod}.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateAgreementAccountsForPerson(string userId, string deliveryMethod, Agreement agreement)
|
||||
{
|
||||
try
|
||||
{
|
||||
var agreementAccounts = await _coreApiWrapperService.GetAgreementAccountsByUserId(agreement.UserId);
|
||||
if (!agreementAccounts.Any()) return;
|
||||
|
||||
_accountNumbers = agreementAccounts.Where(account => account.TaxReportForPersonNumber != null && account.AccountOwner.AgreementNumber == agreement.AgreementNumber).Select(account => account.AccountNumber).ToList();
|
||||
if (_accountNumbers.Any()) await _coreApiWrapperService.UpdateAgreementAccountsDeliveryMethod(_accountNumbers, deliveryMethod, userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var accountsCommaSeperated = string.Join(", ", _accountNumbers.ToArray());
|
||||
await _notificationService.SendDNAUpdateErrorNotification(userId, accountsCommaSeperated, deliveryMethod);
|
||||
var error = $"Failed to UpdateAgreementAccountsDeliveryMethod for accounts: {accountsCommaSeperated} {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateAgreementAccountsForOrganization(string userId, string deliveryMethod, Agreement agreement)
|
||||
{
|
||||
try
|
||||
{
|
||||
var agreementAccounts = await _coreApiWrapperService.GetAgreementAccountsByOrganizationId(agreement.ByOrgNbr);
|
||||
if (!agreementAccounts.Any()) return;
|
||||
|
||||
_accountNumbers = agreementAccounts.Where(account => account.TaxReportForOrgNumber != null && account.AccountOwner.AgreementNumber == agreement.AgreementNumber).Select(account => account.AccountNumber).ToList();
|
||||
if (_accountNumbers.Any()) await _coreApiWrapperService.UpdateAgreementAccountsDeliveryMethod(_accountNumbers, deliveryMethod, userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var accountsCommaSeperated = string.Join(", ", _accountNumbers.ToArray());
|
||||
await _notificationService.SendDNAUpdateErrorNotification(userId, accountsCommaSeperated, deliveryMethod);
|
||||
var error = $"Failed to UpdateAgreementAccountsDeliveryMethod for accounts: {accountsCommaSeperated} {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<MemberPreference>> GetMemberPreferencesAsync(string userId)
|
||||
{
|
||||
var preferences = await _memberPreferenceRepository.GetMemberPreferencesAsync(userId);
|
||||
return preferences ?? new List<MemberPreference>();
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<string> GetAvailableTypes()
|
||||
{
|
||||
return Enum.GetValues(typeof(PreferenceType))
|
||||
.Cast<PreferenceType>()
|
||||
.Select(v => v.ToString())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task UpdateMemberOptinAsync(MemberOptinRequest optinRequest)
|
||||
{
|
||||
if (await _xdiBatchItemService.DoesMemberHavePendingXdiChange(optinRequest.UserId))
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
var oldOptInSettings = await _unifiedOptInRepository.GetMemberOptInSettingsNoTracking(optinRequest.UserId);
|
||||
var requests = new List<MemberPreferenceRequest>();
|
||||
|
||||
if (string.Equals(optinRequest.Value, DeliveryPreference.Electronic, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var unused = new System.Net.Mail.MailAddress(optinRequest.Email);
|
||||
|
||||
requests.Add(
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptInEmail,
|
||||
Value = optinRequest.Email,
|
||||
UserId = optinRequest.UserId,
|
||||
LegalReference = ""
|
||||
});
|
||||
}
|
||||
|
||||
requests.Add(
|
||||
new MemberPreferenceRequest()
|
||||
{
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
Value = optinRequest.Value,
|
||||
UserId = optinRequest.UserId,
|
||||
LegalReference = optinRequest.LegalReference
|
||||
});
|
||||
|
||||
var preferences = await SaveMemberPreferencesAsync(requests);
|
||||
|
||||
await SendOptInChangeNotifications(optinRequest, oldOptInSettings);
|
||||
await _integrationService.NotifyListeners(preferences);
|
||||
}
|
||||
|
||||
public async Task SendOptInChangeNotifications(MemberOptinRequest request, MemberOptInSettings originalSettings)
|
||||
{
|
||||
var affectedEmails = new List<string>();
|
||||
|
||||
TryAddHistoricEmails(originalSettings, affectedEmails);
|
||||
|
||||
//Unknown -> Paper
|
||||
if (originalSettings == null && request.IsPaperRequest())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//NotEmail -> Email
|
||||
if ((originalSettings == null || !originalSettings.IsUnifiedElectronicEnrolled()) &&
|
||||
request.IsElectronicRequest())
|
||||
{
|
||||
affectedEmails.Add(request.Email);
|
||||
await _notificationService.SendOptInNotifications(affectedEmails, request);
|
||||
return;
|
||||
}
|
||||
|
||||
if (originalSettings == null) return;
|
||||
|
||||
//Historic -> Paper
|
||||
if (!originalSettings.HasAnyUnifiedPreference() && request.IsPaperRequest())
|
||||
{
|
||||
await _notificationService.SendOptOutNotifications(affectedEmails);
|
||||
return;
|
||||
}
|
||||
|
||||
//Email -> Paper
|
||||
if (originalSettings.IsUnifiedElectronicEnrolled() && request.IsPaperRequest())
|
||||
{
|
||||
affectedEmails.Add(originalSettings.UnifiedOptInEmail);
|
||||
await _notificationService.SendOptOutNotifications(affectedEmails);
|
||||
return;
|
||||
}
|
||||
|
||||
//Email -> Email
|
||||
if (originalSettings.IsUnifiedElectronicEnrolled() && request.IsElectronicRequest())
|
||||
{
|
||||
if (!string.Equals(originalSettings.UnifiedOptInEmail, request.Email,
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
affectedEmails.Add(originalSettings.UnifiedOptInEmail);
|
||||
affectedEmails.Add(request.Email);
|
||||
await _notificationService.SendEmailChangeNotifications(affectedEmails, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TryAddHistoricEmails(MemberOptInSettings originalSettings, List<string> affectedEmails)
|
||||
{
|
||||
if (originalSettings == null || originalSettings.HasAnyUnifiedPreference()) return;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(originalSettings.EStatementsEmail) && originalSettings.IsOldStatementsElectronicEnrolled())
|
||||
{
|
||||
affectedEmails.Add(originalSettings.EStatementsEmail.ToLowerInvariant());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(originalSettings.ENotificationsEmail) && originalSettings.IsOldNoticesElectronicEnrolled())
|
||||
{
|
||||
affectedEmails.Add(originalSettings.ENotificationsEmail.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices
|
||||
{
|
||||
public class CoreApiWrapperService : ICoreApiWrapperService
|
||||
{
|
||||
private readonly ICoreApiWrapperDao _coreApiWrapperDao;
|
||||
private readonly INotificationService _notificationService;
|
||||
|
||||
public CoreApiWrapperService(ICoreApiWrapperDao coreApiWrapperDao, INotificationService notificationService)
|
||||
{
|
||||
_coreApiWrapperDao = coreApiWrapperDao;
|
||||
_notificationService = notificationService;
|
||||
|
||||
}
|
||||
|
||||
public async Task<Agreement> GetAgreementByUserId(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementByUserId(userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementByUserId. UserId: {userId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Agreement> GetAgreementByAgreementId(long agreementId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementByAgreementId(agreementId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementByAgreementId. AgreementId: {agreementId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Agreement>> GetAgreementsByAccountId(long accountId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementsByAccountId(accountId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementsByAccountId. AccountId: {accountId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<AgreementAccount> GetAgreementAccountByAccountId(long accountId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementAccountByAccountId(accountId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementAccountByAccountId. AccountId: {accountId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByUserId(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementAccountsByUserId(userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementAccountsByUserId. UserId: {userId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByOrganizationId(long organizationId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAgreementAccountsByOrganizationId(organizationId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAgreementAccountsByOrganizationId. OrganizationId: {organizationId} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditAccountsFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAuditAccountsFromDateLastMaintained(dateTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAuditAccountsFromDateLastMaintained. DateTime: {dateTime} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditAgreementFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAuditAgreementFromDateLastMaintained(dateTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAuditAgreementFromDateLastMaintained. DateTime: {dateTime} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<long>> GetAuditOrganizationFromDateLastMaintained(DateTime dateTime)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _coreApiWrapperDao.GetAuditOrganizationFromDateLastMaintained(dateTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to GetAuditOrganizationFromDateLastMaintained. DateTime: {dateTime} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateAgreementAccountsDeliveryMethod(IEnumerable<long> accountIds, string deliveryMethod, string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _coreApiWrapperDao.UpdateAgreementAccountsDeliveryMethod(accountIds, deliveryMethod, userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var accountsCommaSeperated = string.Join(", ", accountIds.ToArray());
|
||||
await _notificationService.SendDNAUpdateErrorNotification(userId, accountsCommaSeperated, deliveryMethod);
|
||||
var error = $"Failed to GetAuditOrganizationFromDateLastMaintained. AccountIds: {accountsCommaSeperated} Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices
|
||||
{
|
||||
public class FtpApiService : IFtpApiService
|
||||
{
|
||||
private readonly IFtpApiDao _ftpApiDao;
|
||||
|
||||
public FtpApiService(IFtpApiDao ftpApiDao)
|
||||
{
|
||||
_ftpApiDao = ftpApiDao;
|
||||
}
|
||||
|
||||
public async Task SendXdiFtpRequest(SshFtpRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _ftpApiDao.SendFtpAsync(request);
|
||||
Log.Information($"XDI Ftp Sent: {request.RemoteFilePath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var error = $"Failed to send FTP file. Exception Message: {ex.Message}";
|
||||
Log.Error(error);
|
||||
throw new ServiceException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
public interface ICoreApiWrapperService
|
||||
{
|
||||
public Task<Agreement> GetAgreementByUserId(string userId);
|
||||
public Task<Agreement> GetAgreementByAgreementId(long agreementId);
|
||||
public Task<IEnumerable<Agreement>> GetAgreementsByAccountId(long accountId);
|
||||
public Task<AgreementAccount> GetAgreementAccountByAccountId(long accountId);
|
||||
public Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByUserId(string userId);
|
||||
public Task<IEnumerable<AgreementAccount>> GetAgreementAccountsByOrganizationId(long organizationId);
|
||||
public Task<IEnumerable<long>> GetAuditAccountsFromDateLastMaintained(DateTime dateTime);
|
||||
public Task<IEnumerable<long>> GetAuditAgreementFromDateLastMaintained(DateTime dateTime);
|
||||
public Task<IEnumerable<long>> GetAuditOrganizationFromDateLastMaintained(DateTime dateTime);
|
||||
public Task UpdateAgreementAccountsDeliveryMethod(IEnumerable<long> accountIds, string deliveryMethod, string userId);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
public interface IFtpApiService
|
||||
{
|
||||
public Task SendXdiFtpRequest(SshFtpRequest request);
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
public interface INotificationService
|
||||
{
|
||||
Task SendOptInNotifications(List<string> recipient, MemberOptinRequest request);
|
||||
Task SendEmailChangeNotifications(List<string> recipient, MemberOptinRequest request);
|
||||
Task SendOptOutNotifications(List<string> recipient);
|
||||
Task SendDNAUpdateErrorNotification(string userId, string accounts, string deliveryMethod);
|
||||
Task SendDNAAgreementErrorNotification(string userId, string deliveryMethod);
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.DataAccess;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
|
||||
public class NotificationService : INotificationService
|
||||
{
|
||||
private readonly NotificationApiConfiguration _notificationsApiConfiguration;
|
||||
private readonly INotificationApiDao _notificationServiceApiDao;
|
||||
|
||||
public NotificationService(NotificationApiConfiguration notificationsApiConfiguration, INotificationApiDao notificationApiDao)
|
||||
{
|
||||
_notificationsApiConfiguration = notificationsApiConfiguration;
|
||||
_notificationServiceApiDao = notificationApiDao;
|
||||
}
|
||||
|
||||
private async Task SendMessageAsync(List<string> recipient, string subject, string body)
|
||||
{
|
||||
if (recipient == null || !recipient.Any())
|
||||
{
|
||||
Log.Information($"A message with subject: {subject} can't be sent to the Notification Api, as no recipients are present.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_notificationsApiConfiguration.ShouldSendRealEmails)
|
||||
{
|
||||
recipient = _notificationsApiConfiguration.TestEmailList;
|
||||
}
|
||||
|
||||
var emailRequest = new EmailRequest
|
||||
{
|
||||
Recipient = recipient,
|
||||
Subject = subject,
|
||||
Body = body
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await _notificationServiceApiDao.SendEmailAsync(emailRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "An exception was caught trying to send an email via Notifications API.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendOptInNotifications(List<string> recipients, MemberOptinRequest request)
|
||||
{
|
||||
var filteredRecipients = recipients.Distinct(StringComparer.InvariantCultureIgnoreCase).ToList();
|
||||
var subject = "Welcome To E-Statements!";
|
||||
var message =
|
||||
$"<div style=\"padding: 2em;\"><p style=\"color: #0054a4;\"><strong>You have enrolled to receive electronic notifications for your statements and notices. You'll love the convenience!</strong></p><p>You will be receiving emails to: {request.Email}</p><p>With electronic statements through Landmark Credit Union Digital Banking, you’ll be able to:</p><ul><li>View your statements and tax documents online or on your mobile device</li><li>Maintain your own secure online archive</li><li>Help the environment by reducing paper and clutter</li></ul><p>You’ll receive an email whenever a new statement becomes available. If you need to make changes to any of your preferences, you can visit Manage Delivery Preferences under Statements & Notices.</p><div style=\"color: #959ba6;\"><center><p style=\"margin:0px;\">You are receiving this email because you enabled e-statements in Landmark Credit Union. If you did not make this selection or believe this is in error, please contact us.</p><p style=\"margin:0px;\"><a href=\"http://www.landmarkcu.com/\">Landmark Credit Union</a> | <a href=\"https://landmarkcu.com/contact-us/\">Contact Us</a></p><p style=\"margin:0px;\">Landmark Credit Union</p><p style=\"margin:0px;\">© 2021 All rights reserved</p></center></div></div>";
|
||||
await SendMessageAsync(filteredRecipients, subject, message);
|
||||
}
|
||||
|
||||
public async Task SendEmailChangeNotifications(List<string> recipients, MemberOptinRequest request)
|
||||
{
|
||||
var filteredRecipients = recipients.Distinct(StringComparer.InvariantCultureIgnoreCase).ToList();
|
||||
var subject = "E-Statements Email Change";
|
||||
var message =
|
||||
$"<div style=\"padding: 2em;\"><p style=\"color: #0054a4;\"><strong>You have changed your preferred email address to receive statement and notice notifications.</strong></p><p>You will now receive emails to: {request.Email}</p><p>Your security is important to us and we wanted to confirm that you recently changed the email address you prefer to use for receiving statement and notice notifications. If this email is incorrect, you can update it in your Landmark Credit Union Digital Banking account by visiting Manage Delivery Preferences under Statements & Notices. If you did not make this change, please contact us.</p><div style=\"color: #959ba6;\"><center><p style=\"margin: 0px;\">You are receiving this email because you updated the email address you are using to receive statement notifications. If you did not make this selection or believe this is in error, please contact us.</p><p style=\"margin: 0px;\"><a href=\"http://www.landmarkcu.com/\">Landmark Credit Union</a> | <a href=\"https://landmarkcu.com/contact-us/\">Contact Us</a></p><p style=\"margin: 0px;\">Landmark Credit Union</p><p style=\"margin: 0px;\">© 2021 All rights reserved</p></center></div></div>";
|
||||
await SendMessageAsync(filteredRecipients, subject, message);
|
||||
}
|
||||
|
||||
public async Task SendOptOutNotifications(List<string> recipients)
|
||||
{
|
||||
var filteredRecipients = recipients.Distinct(StringComparer.InvariantCultureIgnoreCase).ToList();
|
||||
var subject = "Paper Statement Enrollment";
|
||||
var message =
|
||||
$"<div style=\"padding: 2em;\"><p style=\"color: #0054a4;\"><strong>You have enrolled to receive paper for your statements and notices.</strong></p><p>You have selected to receive paper statements and notices. You will no longer be able to view these documents online or on your mobile device.</p><p>With electronic statements through Landmark Credit Union Digital Banking, you’ll be able to:</p><ul><li>View your statements and tax documents online or on your mobile device</li><li>Maintain your own secure online archive</li><li>Help the environment by reducing paper and clutter</li></ul><p>Please note, some accounts may have promotional rates or offers that require paperless statements and electing to receive paper may impact offers on your account. Please refer to your account Truth in Savings disclosure for more information. If you need to make changes to any of your preferences, you can visit Manage Delivery Preferences under Statements & Notices.</p><div style=\"color: #959ba6;\"><center><p style=\"margin:0px;\">You are receiving this email because you requested to receive paper statements and notices. If you did not make this selection or believe this is in error, please contact us.</p><p style=\"margin:0px;\"><a href=\"http://www.landmarkcu.com/\">Landmark Credit Union</a> | <a href=\"https://landmarkcu.com/contact-us/\">Contact Us</a></p><p style=\"margin:0px;\">Landmark Credit Union</p><p style=\"margin:0px;\">© 2021 All rights reserved</p></center></div></div>";
|
||||
await SendMessageAsync(filteredRecipients, subject, message);
|
||||
}
|
||||
|
||||
public async Task SendDNAUpdateErrorNotification(string userId, string accounts, string deliveryMethod)
|
||||
{
|
||||
const string subject = "ERROR: Unified Opt In Tool Encountered an Error updating DNA";
|
||||
var message =
|
||||
$"<br/><br/><h3>Unified Opt In Tool Encountered an Error updating DNA</h3><hr/> Unified Opt In Tool was unable to sync a member’s selected preference with DNA due to an unexpected error. Please investigate and manually update the following account(s) delivery method in DNA if the change is valid.<br><br><b>Member’s eAgreement User Id:</b> {userId}<br><b>Affected accounts owned by person:</b> {accounts}<br><b>Attempting to update to:</b> {deliveryMethod}";
|
||||
await SendMessageAsync(_notificationsApiConfiguration.DNACoreErrorEmailList, subject, message);
|
||||
}
|
||||
|
||||
public async Task SendDNAAgreementErrorNotification(string userId, string deliveryMethod)
|
||||
{
|
||||
const string subject = "ERROR: Unified Opt In Tool Encountered an Error finding Agreement in DNA";
|
||||
var message = $"<br/><br/><h3>Unified Opt In Tool Encountered an Error finding Agreement in DNA</h3><hr/> Unified Opt In Tool was unable to sync a member’s selected preference with DNA due to an unexpected error. Please investigate and manually update the accounts associated delivery method in DNA if the change is valid.<br><br><b>Member’s eAgreement User Id:</b> {userId}<br><b>Attempting to update to:</b> {deliveryMethod}";
|
||||
await SendMessageAsync(_notificationsApiConfiguration.DNACoreErrorEmailList, subject, message);
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.DataTransfer;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public class OptinService : IOptinService
|
||||
{
|
||||
private readonly IUnifiedOptInRepository _unifiedOptInRepository;
|
||||
private readonly IXdiBatchService _xdiBatchItemService;
|
||||
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
||||
private readonly IMemberPreferenceService _memberPreferenceService;
|
||||
|
||||
public OptinService(IUnifiedOptInRepository unifiedOptInRepository, IXdiBatchService xdiBatchItemService, IMemberPreferenceService memberPreferenceService,
|
||||
ICoreApiWrapperService coreApiWrapperService)
|
||||
{
|
||||
_unifiedOptInRepository = unifiedOptInRepository;
|
||||
_xdiBatchItemService = xdiBatchItemService;
|
||||
_memberPreferenceService = memberPreferenceService;
|
||||
_coreApiWrapperService = coreApiWrapperService;
|
||||
}
|
||||
|
||||
public async Task<MemberOptInSettings> GetMemberOptInSettings(string userId)
|
||||
{
|
||||
return await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
}
|
||||
|
||||
public async Task<MemberOptInSettings> GetMemberOptInSettingsOrCreateDefaultSetting(string userId)
|
||||
{
|
||||
var memberOptInSettings = await _unifiedOptInRepository.GetMemberOptInSettings(userId);
|
||||
|
||||
try
|
||||
{
|
||||
if (memberOptInSettings == null)
|
||||
{
|
||||
var memberPreferenceRequest = new MemberPreferenceRequest()
|
||||
{
|
||||
UserId = userId,
|
||||
Preference = PreferenceType.UnifiedOptIn,
|
||||
LegalReference = DateTime.Now.ToString("s"),
|
||||
Value = "Paper"
|
||||
};
|
||||
|
||||
memberOptInSettings = await _memberPreferenceService.SaveMemberPreferenceDefaultAsync(memberPreferenceRequest, "System", UserType.System, DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to create new MemberOptInSettings with default of paper for UserId: {userId}");
|
||||
}
|
||||
|
||||
return memberOptInSettings;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<MemberOptInAgreementInformation>> GetMemberOptInAgreementInformationByAccountId(long accountId)
|
||||
{
|
||||
var response = new List<MemberOptInAgreementInformation>();
|
||||
|
||||
var agreements = await _coreApiWrapperService.GetAgreementsByAccountId(accountId);
|
||||
if (agreements == null || !agreements.Any()) return response;
|
||||
foreach (var agreement in agreements)
|
||||
{
|
||||
var accounts = await GetAgreementAccountsForAgreement(agreement);
|
||||
var memberOptinSettings = await _unifiedOptInRepository.GetMemberOptInSettings(agreement.UserId);
|
||||
var isPending = await _xdiBatchItemService.DoesMemberHavePendingXdiChange(agreement.UserId);
|
||||
response.Add(new MemberOptInAgreementInformation(memberOptinSettings, agreement, accounts, isPending));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<AgreementAccount>> GetAgreementAccountsForAgreement(Agreement agreement)
|
||||
{
|
||||
IEnumerable<AgreementAccount> accounts;
|
||||
|
||||
if (agreement.ByOrgNbr != 0)
|
||||
{
|
||||
accounts = await _coreApiWrapperService.GetAgreementAccountsByOrganizationId(agreement.ByOrgNbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
accounts = await _coreApiWrapperService.GetAgreementAccountsByUserId(agreement.UserId);
|
||||
}
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
public async Task<MemberOptInAgreementInformation> GetMemberOptInAgreementInformationForUser(string userId)
|
||||
{
|
||||
var agreement = await _coreApiWrapperService.GetAgreementByUserId(userId);
|
||||
var memberOptinSettings = await GetMemberOptInSettingsOrCreateDefaultSetting(userId);
|
||||
var isPending = await _xdiBatchItemService.DoesMemberHavePendingXdiChange(userId);
|
||||
|
||||
if (agreement == null)
|
||||
{
|
||||
return new MemberOptInAgreementInformation(memberOptinSettings, null, null, isPending);
|
||||
}
|
||||
|
||||
var accounts = await GetAgreementAccountsForAgreement(agreement);
|
||||
return new MemberOptInAgreementInformation(memberOptinSettings, agreement, accounts, isPending);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyCollection<MemberOptInInformation>> TransformMemberOptInSettingsForClient(List<MemberOptInSettings> memberOptInSettingsList)
|
||||
{
|
||||
var response = new List<MemberOptInInformation>();
|
||||
|
||||
foreach (var setting in memberOptInSettingsList)
|
||||
{
|
||||
var isPending = await _xdiBatchItemService.DoesMemberHavePendingXdiChange(setting.UserId);
|
||||
response.Add(new MemberOptInInformation(setting, isPending));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public async Task<MemberOptInInformation> TransformMemberOptInSettingsForClient(MemberOptInSettings memberOptInSettings)
|
||||
{
|
||||
var results = await TransformMemberOptInSettingsForClient(new List<MemberOptInSettings> { memberOptInSettings });
|
||||
return results.Single();
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public interface IQueueDnaAccountAuditService
|
||||
{
|
||||
Task QueueDataAuditForAccounts(List<long> accountNumbers, int consecutiveFailures = 0);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public interface IQueueDnaAgreementAuditService
|
||||
{
|
||||
Task QueueDataAuditForAgreements(List<long> agreementAuditRecords, int consecutiveFailures = 0);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public interface IQueueDnaOrganizationAuditService
|
||||
{
|
||||
Task QueueDataAuditForOrganizations(List<long> organizationNumbers, int consecutiveFailures = 0);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public interface IQueueXdiBatchService
|
||||
{
|
||||
Task QueueXdiBatchProcess(XdiBatchRequest request);
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices
|
||||
{
|
||||
public class QueueDnaAccountAuditService : IQueueDnaAccountAuditService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
private readonly ReceiveEndpointConfiguration _dnaAccountAuditReceiveEndpoint;
|
||||
|
||||
public QueueDnaAccountAuditService(IBusControl busControl, ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_dnaAccountAuditReceiveEndpoint = receiveEndpointConfigurations.DnaAccountAuditEndpoint;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(_dnaAccountAuditReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueDataAuditForAccounts(List<long> accountAuditRecords, int consecutiveFailures = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var account in accountAuditRecords)
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
DnaFieldIdInformation = account,
|
||||
ConsecutiveFailures = consecutiveFailures,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAccounts,
|
||||
LastUpdated = DateTime.UtcNow,
|
||||
ProcessId = 2
|
||||
};
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group), Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(ex, "Failed to Queue MemberPreference DNA Account Audit records.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public class QueueDnaAgreementAuditService : IQueueDnaAgreementAuditService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
private readonly ReceiveEndpointConfiguration _dnaAuditAgreementReceiveEndpoint;
|
||||
|
||||
public QueueDnaAgreementAuditService(IBusControl busControl, ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_dnaAuditAgreementReceiveEndpoint = receiveEndpointConfigurations.DnaAgreementAuditEndpoint;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(_dnaAuditAgreementReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueDataAuditForAgreements(List<long> agreementAuditRecords, int consecutiveFailures = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var agreement in agreementAuditRecords)
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
DnaFieldIdInformation = agreement,
|
||||
ConsecutiveFailures = consecutiveFailures,
|
||||
DnaProcessType = DnaAuditProcessType.DNAAgreement,
|
||||
LastUpdated = DateTime.UtcNow,
|
||||
ProcessId = 1
|
||||
};
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group), Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(ex, "Failed to Queue MemberPreference DNA Account Audit records.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
|
||||
|
||||
public class QueueDnaOrganizationService : IQueueDnaOrganizationAuditService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
private readonly ReceiveEndpointConfiguration _dnaAuditOrganizationReceiveEndpoint;
|
||||
|
||||
public QueueDnaOrganizationService(IBusControl busControl, ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_dnaAuditOrganizationReceiveEndpoint = receiveEndpointConfigurations.DnaOrganizationAuditEndpoint;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(_dnaAuditOrganizationReceiveEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueDataAuditForOrganizations(List<long> organizationAuditRecords, int consecutiveFailures = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var organization in organizationAuditRecords)
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var request = new DnaFieldChangeRequest()
|
||||
{
|
||||
DnaFieldIdInformation = organization,
|
||||
ConsecutiveFailures = consecutiveFailures,
|
||||
DnaProcessType = DnaAuditProcessType.DNAOrganization,
|
||||
LastUpdated = DateTime.UtcNow,
|
||||
ProcessId = 3
|
||||
|
||||
};
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group), Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(ex, "Failed to Queue MemberPreference DNA Account Audit records.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using MassTransit;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.QueueServices
|
||||
{
|
||||
public class QueueXdiBatchService : IQueueXdiBatchService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
private readonly ReceiveEndpointConfiguration _xdiServiceEndpoint;
|
||||
|
||||
public QueueXdiBatchService(IBusControl busControl, ReceiveEndpointConfigurations receiveEndpointConfigurations)
|
||||
{
|
||||
_xdiServiceEndpoint = receiveEndpointConfigurations.XdiBatchProcessEndpoint;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(_xdiServiceEndpoint.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public async Task QueueXdiBatchProcess(XdiBatchRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group), Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Error(ex, "Failed to Queue XdiBatchProcess.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ReadsCurrentUserAttribute : Attribute
|
||||
{
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services;
|
||||
|
||||
public class ReadsCurrentUserOperationFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
if (context.MethodInfo.GetCustomAttribute<ReadsCurrentUserAttribute>() is null) return;
|
||||
|
||||
operation.Parameters ??= new List<OpenApiParameter>();
|
||||
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "UserName",
|
||||
In = ParameterLocation.Header,
|
||||
Required = true,
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
});
|
||||
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "UserType",
|
||||
In = ParameterLocation.Header,
|
||||
Required = true,
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Enum = Enum.GetValues(typeof(UserType))
|
||||
.Cast<UserType>()
|
||||
.Select(t => new OpenApiString(t.ToString()))
|
||||
.ToList<IOpenApiAny>()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
|
||||
public interface IXdiBatchProcessService
|
||||
{
|
||||
Task RunXdiBatchProcess(string sftpRootBasePath);
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using LCU.API.Internal.MemberPreferencesApi.Models;
|
||||
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
|
||||
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
|
||||
|
||||
namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
|
||||
|
||||
public interface IXdiBatchService
|
||||
{
|
||||
Task AddXdiBatchItem(XdiBatchItem newItem);
|
||||
Task CreateXdiBatchFiles(XdiBatchRequest request);
|
||||
Task<XdiBatchRequest> BuildXdiBatchRequest(XdiBatchRequest request);
|
||||
Task HandleFtpProcess(XdiBatchRequest request);
|
||||
Task<bool> RequestFtpTransport(IReadOnlyCollection<XdiBatchFile> files);
|
||||
Task<bool> MarkPendingSuccessful(ApiResponse.Response response);
|
||||
Task<List<FtpQueuePayloadItem>> CreateFtpPayload(XdiBatchFile xdiBatchFile);
|
||||
Task<bool> DoesMemberHavePendingXdiChange(string memberId);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user