-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Hekku2/feat/randomization
Improve image randomization
- Loading branch information
Showing
10 changed files
with
239 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
# TODO | ||
* Validate that Discord configuration is given | ||
* Validate image source configuration | ||
* Validate index configuration | ||
* Add CI | ||
* Document architecture | ||
* Add support for Managed identity authentication for storage access |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using DiscordImagePoster.Common.IndexService; | ||
|
||
namespace DiscordImagePoster.Common.RandomizationService; | ||
|
||
/// <summary> | ||
/// Randomization service proivdes randomization logic for ImageIndex | ||
/// </summary> | ||
public interface IRandomizationService | ||
{ | ||
/// <summary> | ||
/// Returns random image from given image index. | ||
/// </summary> | ||
/// <param name="imageIndex">Index</param> | ||
/// <returns>Random image from index or null if there are no valid images available.</returns> | ||
ImageIndexMetadata? GetRandomImage(ImageIndex imageIndex); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using DiscordImagePoster.Common.IndexService; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace DiscordImagePoster.Common.RandomizationService; | ||
|
||
public class RandomizationService : IRandomizationService | ||
{ | ||
private readonly ILogger<RandomizationService> _logger; | ||
|
||
public RandomizationService(ILogger<RandomizationService> logger) | ||
{ | ||
_logger = logger; | ||
} | ||
|
||
public ImageIndexMetadata? GetRandomImage(ImageIndex imageIndex) | ||
{ | ||
_logger.LogTrace("Getting random image from image index."); | ||
|
||
var allowedImages = imageIndex.Images.Where(image => !image.Ignore); | ||
if (!allowedImages.Any()) | ||
{ | ||
_logger.LogTrace("No allowed images found in index."); | ||
return null; | ||
} | ||
var minimunPosts = allowedImages.Min(image => image.TimesPosted); | ||
_logger.LogTrace("Minimum posts for allowed images: {MinimunPosts}", minimunPosts); | ||
return allowedImages | ||
.Where(image => image.TimesPosted == minimunPosts) | ||
.OrderBy(x => Guid.NewGuid()) | ||
.FirstOrDefault(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
<RootNamespace>Tests.Common</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FluentAssertions" Version="6.12.0" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> | ||
<PackageReference Include="NSubstitute" Version="5.1.0" /> | ||
<PackageReference Include="NUnit" Version="4.1.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> | ||
<PackageReference Include="NUnit.Analyzers" Version="4.2.0" /> | ||
<PackageReference Include="coverlet.collector" Version="6.0.2" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Common\Common.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
global using NUnit.Framework; |
123 changes: 123 additions & 0 deletions
123
tests/CommonTests/RandomizationService/RandomizationServiceTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
using Castle.Core.Logging; | ||
using DiscordImagePoster.Common.IndexService; | ||
using DiscordImagePoster.Common.RandomizationService; | ||
using FluentAssertions; | ||
using Microsoft.Extensions.Logging; | ||
using NSubstitute; | ||
|
||
namespace Tests.Common; | ||
|
||
public class RandomizationServiceTests | ||
{ | ||
private RandomizationService _randomizationService; | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
ILogger<RandomizationService> mockLogger = Substitute.For<ILogger<RandomizationService>>(); | ||
|
||
_randomizationService = new RandomizationService(mockLogger); | ||
|
||
} | ||
|
||
[Test] | ||
public void GetRandomImage_ForEmptyCollection_ReturnsNull() | ||
{ | ||
var imageIndex = new ImageIndex() | ||
{ | ||
RefreshedAt = DateTimeOffset.UtcNow, | ||
Images = new List<ImageIndexMetadata>() | ||
}; | ||
|
||
var result = _randomizationService.GetRandomImage(imageIndex); | ||
|
||
result.Should().BeNull(); | ||
} | ||
|
||
|
||
[Test] | ||
public void GetRandomImage_ForIgnoredImages_ReturnsNull() | ||
{ | ||
var imageIndex = new ImageIndex() | ||
{ | ||
RefreshedAt = DateTimeOffset.UtcNow, | ||
Images = new List<ImageIndexMetadata> | ||
{ | ||
new ImageIndexMetadata | ||
{ | ||
Ignore = true, | ||
AddedAt = DateTime.UtcNow, | ||
Description = null, | ||
LastPostedAt = null, | ||
TimesPosted = 0, | ||
Name = "Test Image" | ||
} | ||
} | ||
}; | ||
|
||
var result = _randomizationService.GetRandomImage(imageIndex); | ||
|
||
result.Should().BeNull(); | ||
} | ||
|
||
[Test] | ||
public void GetRandomImage_ForSomeImage_ReturnsImage() | ||
{ | ||
var imageIndex = new ImageIndex() | ||
{ | ||
RefreshedAt = DateTimeOffset.UtcNow, | ||
Images = new List<ImageIndexMetadata> | ||
{ | ||
new ImageIndexMetadata | ||
{ | ||
Ignore = false, | ||
AddedAt = DateTime.UtcNow, | ||
Description = null, | ||
LastPostedAt = null, | ||
TimesPosted = 27, | ||
Name = "Test Image" | ||
} | ||
} | ||
}; | ||
|
||
var result = _randomizationService.GetRandomImage(imageIndex); | ||
|
||
result.Should().BeEquivalentTo(imageIndex.Images.First()); | ||
} | ||
|
||
[Test] | ||
public void GetRandomImage_TwoImages_ReturnsLessPostedImage() | ||
{ | ||
var imageIndex = new ImageIndex() | ||
{ | ||
RefreshedAt = DateTimeOffset.UtcNow, | ||
Images = new List<ImageIndexMetadata> | ||
{ | ||
new ImageIndexMetadata | ||
{ | ||
Ignore = false, | ||
AddedAt = DateTime.UtcNow, | ||
Description = null, | ||
LastPostedAt = null, | ||
TimesPosted = 27, | ||
Name = "Test Image 1" | ||
}, | ||
new ImageIndexMetadata | ||
{ | ||
Ignore = false, | ||
AddedAt = DateTime.UtcNow, | ||
Description = null, | ||
LastPostedAt = null, | ||
TimesPosted = 25, | ||
Name = "Test Image 2" | ||
} | ||
} | ||
}; | ||
|
||
for (var i = 0; i < 10; i++) | ||
{ | ||
var result = _randomizationService.GetRandomImage(imageIndex); | ||
result.Should().BeEquivalentTo(imageIndex.Images.Last()); | ||
} | ||
} | ||
} |