Skip to content

Commit

Permalink
Implement sms-repo for create (#400)
Browse files Browse the repository at this point in the history
* Implement sms-repo for create

* Apply suggestions from code review

* Update test/Altinn.Notifications.IntegrationTests/Notifications.Persistence/SmsRepositoryTests.cs

* Updatre SmsNotification value

---------

Co-authored-by: Stephanie Buadu <47737608+acn-sbuad@users.noreply.github.com>
  • Loading branch information
tba76 and acn-sbuad authored Jan 30, 2024
1 parent 9b3ee57 commit 8864150
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Altinn.Notifications.Core/Enums/SmsNotificationResultType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Altinn.Notifications.Core.Enums;

/// <summary>
/// Enum describing sms notification result types
/// </summary>
public enum SmsNotificationResultType
{
/// <summary>
/// Default result for new notifications
/// </summary>
New,

/// <summary>
/// Sms notification being sent
/// </summary>
Sending,

/// <summary>
/// Sms notification sent to service provider
/// </summary>
Accepted,

/// <summary>
/// Failed, unknown reason
/// </summary>
Failed,

/// <summary>
/// Failed, invalid mobilenumber
/// </summary>
Failed_InvalidRecipient
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Altinn.Notifications.Core.Enums;

namespace Altinn.Notifications.Core.Models.Notification;

/// <summary>
/// Class describing an sns notification and extends the <see cref="INotification{SmsNotificationResultType}"/>
/// </summary>
public class SmsNotification : INotification<SmsNotificationResultType>
{
/// <inheritdoc/>
public Guid Id { get; internal set; }

/// <inheritdoc/>
public Guid OrderId { get; internal set; }

/// <inheritdoc/>
public DateTime RequestedSendTime { get; internal set; }

/// <inheritdoc/>
public NotificationChannel NotificationChannel { get; } = NotificationChannel.Sms;

/// <summary>
/// Get the id of the recipient of the sms notification
/// </summary>
public string? RecipientId { get; internal set; }

/// <summary>
/// Get or sets the mobilenumber of the sms notification
/// </summary>
public string RecipientNumber { get; internal set; } = string.Empty;

/// <inheritdoc/>
public NotificationResult<SmsNotificationResultType> SendResult { get; internal set; } = new(SmsNotificationResultType.New, DateTime.UtcNow);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Altinn.Notifications.Core.Models.Notification;

namespace Altinn.Notifications.Core.Persistence;

/// <summary>
/// Interface describing all repository operations related to an sms notification
/// </summary>
public interface ISmsNotificationRepository
{
/// <summary>
/// Adds a new sms notification to the database
/// </summary>
public Task AddNotification(SmsNotification notification, DateTime expiry);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public static IServiceCollection AddPostgresRepositories(this IServiceCollection
return services
.AddSingleton<IOrderRepository, OrderRepository>()
.AddSingleton<IEmailNotificationRepository, EmailNotificationRepository>()
.AddSingleton<ISmsNotificationRepository, SmsNotificationRepository>()
.AddSingleton<INotificationSummaryRepository, NotificationSummaryRepository>()
.AddSingleton<IResourceLimitRepository, ResourceLimitRepository>()
.AddNpgsqlDataSource(connectionString, builder =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CREATE OR REPLACE PROCEDURE notifications.insertsmsnotification(_orderid uuid,
_alternateid uuid,
_recipientid TEXT,
_mobilenumber TEXT,
_result text,
_resulttime timestamptz,
_expirytime timestamptz
)
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
__orderid BIGINT := (SELECT _id from notifications.orders
where alternateid = _orderid);
BEGIN

INSERT INTO notifications.smsnotifications(_orderid, alternateid, recipientid, mobilenumber, result, resulttime, expirytime)
VALUES (__orderid, _alternateid, _recipientid, _mobilenumber, _result::smsnotificationresulttype, _resulttime, _expirytime);
END;
$BODY$
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Altinn.Notifications.Core.Models.Notification;
using Altinn.Notifications.Core.Persistence;
using Microsoft.ApplicationInsights;
using Npgsql;
using NpgsqlTypes;

namespace Altinn.Notifications.Persistence.Repository;

/// <summary>
/// Implementation of sms repository logic
/// </summary>
public class SmsNotificationRepository : ISmsNotificationRepository
{
private readonly NpgsqlDataSource _dataSource;
private readonly TelemetryClient? _telemetryClient;

private const string _insertSmsNotificationSql = "call notifications.insertsmsnotification($1, $2, $3, $4, $5, $6, $7)"; // (__orderid, _alternateid, _recipientid, _mobilenumber, _result, _resulttime, _expirytime)

/// <summary>
/// Initializes a new instance of the <see cref="SmsNotificationRepository"/> class.
/// </summary>
/// <param name="dataSource">The npgsql data source.</param>
/// <param name="telemetryClient">Telemetry client</param>
public SmsNotificationRepository(NpgsqlDataSource dataSource, TelemetryClient? telemetryClient = null)
{
_dataSource = dataSource;
_telemetryClient = telemetryClient;
}

/// <inheritdoc/>
public async Task AddNotification(SmsNotification notification, DateTime expiry)
{
await using NpgsqlCommand pgcom = _dataSource.CreateCommand(_insertSmsNotificationSql);
using TelemetryTracker tracker = new(_telemetryClient, pgcom);

pgcom.Parameters.AddWithValue(NpgsqlDbType.Uuid, notification.OrderId);
pgcom.Parameters.AddWithValue(NpgsqlDbType.Uuid, notification.Id);
pgcom.Parameters.AddWithValue(NpgsqlDbType.Text, notification.RecipientId ?? (object)DBNull.Value);
pgcom.Parameters.AddWithValue(NpgsqlDbType.Text, notification.RecipientNumber);
pgcom.Parameters.AddWithValue(NpgsqlDbType.Text, notification.SendResult.Result.ToString());
pgcom.Parameters.AddWithValue(NpgsqlDbType.TimestampTz, notification.SendResult.ResultTime);
pgcom.Parameters.AddWithValue(NpgsqlDbType.TimestampTz, expiry);

await pgcom.ExecuteNonQueryAsync();
tracker.Track();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Altinn.Notifications.Core.Enums;
using Altinn.Notifications.Core.Models.Notification;
using Altinn.Notifications.Core.Models.Orders;
using Altinn.Notifications.Core.Persistence;
using Altinn.Notifications.IntegrationTests.Utils;
using Altinn.Notifications.Persistence.Repository;
using Xunit;

namespace Altinn.Notifications.IntegrationTests.Notifications.Persistence;

public class SmsRepositoryTests : IAsyncLifetime
{
private List<Guid> orderIdsToDelete;

public SmsRepositoryTests()
{
orderIdsToDelete = [];
}

public async Task InitializeAsync()
{
await Task.CompletedTask;
}

public async Task DisposeAsync()
{
string deleteSql = $@"DELETE from notifications.orders o where o.alternateid in ('{string.Join("','", orderIdsToDelete)}')";
await PostgreUtil.RunSql(deleteSql);
}

[Fact]
public async Task Create_SmsNotification()
{
// Arrange
Guid orderId = await PostgreUtil.PopulateDBWithOrderAndReturnId();
orderIdsToDelete.Add(orderId);

// Arrange
SmsNotificationRepository repo = (SmsNotificationRepository)ServiceUtil
.GetServices(new List<Type>() { typeof(ISmsNotificationRepository) })
.First(i => i.GetType() == typeof(SmsNotificationRepository));

Guid notificationId = Guid.NewGuid();
SmsNotification smsNotification = new()
{
Id = notificationId,
OrderId = orderId,
RequestedSendTime = DateTime.UtcNow,
RecipientId = "12345678",
RecipientNumber = "999999999",
};

await repo.AddNotification(smsNotification, DateTime.UtcNow);

// Assert
string sql = $@"SELECT count(1)
FROM notifications.smsnotifications o
WHERE o.alternateid = '{notificationId}'";

int actualCount = await PostgreUtil.RunSqlReturnOutput<int>(sql);

Assert.Equal(1, actualCount);
}
}

0 comments on commit 8864150

Please sign in to comment.