Skip to content

Commit

Permalink
feat: add message
Browse files Browse the repository at this point in the history
  • Loading branch information
sixwaaaay committed Jan 17, 2024
1 parent ea7fbeb commit 6667c61
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 4 deletions.
24 changes: 20 additions & 4 deletions .github/chore/content.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,28 @@
* limitations under the License.
*/


CREATE TABLE `notifications`
(
`id` BIGINT NOT NULL AUTO_INCREMENT,
`sender_id` BIGINT NOT NULL,
`receiver_id` BIGINT NOT NULL,
`content` varchar(255) NOT NULL,
`type` TINYINT unsigned NOT NULL DEFAULT 0,
`status` TINYINT unsigned NOT NULL DEFAULT 0,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `query_by_receiver_id` (`status`,`receiver_id`,`id` ASC)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE videos
(
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT NOT NULL,
title VARCHAR(255) NOT NULL,
des TEXT NOT NULL,
des VARCHAR(255) NOT NULL,
cover_url VARCHAR(255) NOT NULL default '',
video_url VARCHAR(255) NOT NULL default '',
duration INT UNSIGNED,
Expand All @@ -26,15 +42,15 @@ CREATE TABLE videos
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
processed TINYINT NOT NULL DEFAULT 0,
PRIMARY KEY (id),
KEY `user_created` (`processed`, `user_id`, `id` DESC),
KEY `processed` (`processed`, `id` DESC)
KEY `user_created` (`processed`, `user_id`, `id` DESC),
KEY `processed` (`processed`, `id` DESC)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

CREATE TABLE counter
(
id BIGINT NOT NULL,
id BIGINT NOT NULL,
counter INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE = InnoDB
Expand Down
85 changes: 85 additions & 0 deletions sharp/content.Tests/repository/NotificationRepositoryTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
namespace content.Tests.repository;

using MySqlConnector;
using Xunit;
using System.Collections.Generic;
using System.Threading.Tasks;
using content.repository;

public class NotificationRepositoryTests
{
private readonly NotificationRepository _repository;

public NotificationRepositoryTests()
{
var dataSource = new MySqlDataSource(Environment.GetEnvironmentVariable("CONNECTION_STRING") !);
_repository = new NotificationRepository(dataSource);
}

[Fact]
public async Task FindByReceiverId_ReturnsNotifications_WhenUnreadOnlyIsFalse()
{
// Arrange
const long receiverId = 1L;
const long page = 0L;
const int size = 10;

// Act
var result = await _repository.FindByReceiverId(receiverId, page, size);

// Assert
Assert.NotNull(result);
Assert.IsType<List<Message>>(result);
}

[Fact]
public async Task FindByReceiverId_ReturnsUnreadNotifications_WhenUnreadOnlyIsTrue()
{
// Arrange
const long receiverId = 1L;
const long page = 0L;
const int size = 10;
const bool unreadOnly = true;

// Act
var result = await _repository.FindByReceiverId(receiverId, page, size, unreadOnly);

// Assert
Assert.NotNull(result);
Assert.IsType<List<Message>>(result);
}

[Fact]
public async Task Save_ReturnsNotification_WhenInsertIsSuccessful()
{
// Arrange
var notification = new Message
{
SenderId = 1L,
ReceiverId = 2L,
Content = "Test content",
Type = 1,
};

// Act
var result = await _repository.Save(notification);

// Assert
Assert.NotNull(result);
Assert.IsType<Message>(result);
}

[Fact]
public async Task UpdateStatus_UpdatesNotificationStatus()
{
// Arrange
const long id = 1L;
const int status = 1;

// Act
await _repository.UpdateStatus(id, status);

// Assert
// No exception means the test passed
}
}
82 changes: 82 additions & 0 deletions sharp/content/repository/Notification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2023-2024 sixwaaaay.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using Dapper;
using MySqlConnector;

namespace content.repository;

public record Message

Check warning on line 19 in sharp/content/repository/Notification.cs

View check run for this annotation

Codecov / codecov/patch

sharp/content/repository/Notification.cs#L19

Added line #L19 was not covered by tests
{
public long Id { get; set; }
public long SenderId { get; init; }
public long ReceiverId { get; init; }
public string Content { get; init; } = string.Empty;
public short Type { get; init; }
public short Status { get; init; }
public DateTime CreatedAt { get; init; } = DateTime.Now;
}

public interface INotificationRepository
{
ValueTask<IReadOnlyList<Message>> FindByReceiverId(long receiverId, long page, int size, bool unreadOnly);

ValueTask<Message> Save(Message notification);
ValueTask UpdateStatus(long id, short status);
}

public class NotificationRepository(MySqlDataSource dataSource) : INotificationRepository
{
public async ValueTask<IReadOnlyList<Message>> FindByReceiverId(long receiverId, long page, int size,
bool unreadOnly = false)
{
await using var connection = await dataSource.OpenConnectionAsync();
if (unreadOnly)
{
var messageNotifications = await connection.QueryAsync<Message>(
"SELECT id, sender_id, receiver_id, content, type, status, created_at " +
"FROM notifications WHERE receiver_id = @receiverId AND status = 0 " +
"AND id > @page limit @size", new { receiverId, page, size });
return messageNotifications.ToList();
}

var notifications = await connection.QueryAsync<Message>(
"SELECT id, sender_id, receiver_id, content, type, status, created_at " +
"FROM notifications WHERE receiver_id = @receiverId " +
"AND id > @page limit @size",
new { receiverId, page, size });
return notifications.ToList();
}

public async ValueTask<Message> Save(Message notification)
{
await using var connection = await dataSource.OpenConnectionAsync();
var result = await connection.ExecuteAsync(
"INSERT INTO notifications (sender_id, receiver_id, content, type, status, created_at) " +
"VALUES (@SenderId, @ReceiverId, @Content, @Type, @Status, @CreatedAt)", notification);
if (result == 0)
{
throw new Exception("Insert notification failed");

Check warning on line 69 in sharp/content/repository/Notification.cs

View check run for this annotation

Codecov / codecov/patch

sharp/content/repository/Notification.cs#L68-L69

Added lines #L68 - L69 were not covered by tests
}

notification.Id = await connection.QuerySingleAsync<long>("SELECT LAST_INSERT_ID()");
return notification;
}

public async ValueTask UpdateStatus(long id, short status)
{
await using var connection = await dataSource.OpenConnectionAsync();
await connection.ExecuteAsync(
"UPDATE notifications SET status = @status WHERE id = @id", new { id, status });
}
}

0 comments on commit 6667c61

Please sign in to comment.