diff --git a/README.md b/README.md index ea4f07b..cc6f1d2 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ MeiliSearch .NET Integration is a NuGet package that seamlessly embeds MeiliSearch into your C# application. It manages the background process and health checks for you, simplifying the integration of full-text search capabilities. In future updates, it will also handle automatic compression and decompression of indexes to help manage local storage usage effectively. +`You can use the default SDK for everything, but indexs that are disabled through the SDK wont appear until reenabled with the SDK.` + ## Features - [x] **Embedded MeiliSearch**: Integrate MeiliSearch directly into your application. diff --git a/meilisearch.NET.Tests/MeiliSearchServiceTests.cs b/meilisearch.NET.Tests/MeiliSearchServiceTests.cs deleted file mode 100644 index d138e5e..0000000 --- a/meilisearch.NET.Tests/MeiliSearchServiceTests.cs +++ /dev/null @@ -1,394 +0,0 @@ -using Xunit; -using meilisearch.NET; -using Microsoft.Extensions.Logging; -using meilisearch.NET.Configurations; -using System.Net.Http; -using Moq; -using Meilisearch; -using Microsoft.Extensions.Configuration; -using System.Threading.Tasks; -using System.Collections.Generic; -using meilisearch.NET.Interfaces; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.IO; -using System.Threading; -using System.Collections.ObjectModel; - -namespace meilisearch.NET.Tests; - -public class MeiliSearchServiceTests -{ - private readonly Mock _httpClientMock; - private readonly Mock> _loggerMock; - private readonly Mock _meiliConfigurationMock; - private readonly MeiliSearchService _meiliSearchService; - - public MeiliSearchServiceTests() - { - _httpClientMock = new Mock(); - _loggerMock = new Mock>(); - _meiliConfigurationMock = new Mock(); - _meiliConfigurationMock.Setup(x => x.MeiliPort).Returns(7700); - - _meiliSearchService = new MeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object); - } - - [Fact] - public void Test_Service_Initialized() - { - Assert.NotNull(_meiliSearchService); - } - - [Fact] - public async Task Test_StartMeilisearch_Success() - { - // Mock the process start - var processMock = new Mock(); - processMock.Setup(p => p.Start()).Returns(true); - - // Mock the Process.Start method - Mock processWrapperMock = new Mock(); - processWrapperMock.Setup(p => p.Start(It.IsAny())).Returns(processMock.Object); - - // Override the GetMeilisearchBinaryName method - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, processWrapperMock.Object); - - // Call the StartMeilisearch method - await meiliSearchService.StartMeilisearch(); - - // Assert that the process was started - processWrapperMock.Verify(p => p.Start(It.IsAny()), Times.Once); - } - - [Fact] - public void Test_Stop_Success() - { - // Mock the process - var processMock = new Mock(); - processMock.Setup(p => p.Kill()); - - // Set the process to the MeiliSearchService - _meiliSearchService.process = processMock.Object; - - // Call the Stop method - _meiliSearchService.Stop(); - - // Assert that the process was killed - processMock.Verify(p => p.Kill(), Times.Once); - } - - [Fact] - public void Test_IsMeilisearchRunning_Success() - { - // Mock the Process.GetProcessesByName method - var processMock = new Mock(); - var processes = new Process[] { processMock.Object }; - Mock processStaticWrapperMock = new Mock(); - processStaticWrapperMock.Setup(p => p.GetProcessesByName(It.IsAny())).Returns(processes); - - // Override the GetMeilisearchBinaryName method - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, null, processStaticWrapperMock.Object); - - // Call the IsMeilisearchRunning method - var isRunning = meiliSearchService.IsMeilisearchRunning(); - - // Assert that the method returns true - Assert.True(isRunning); - } - - [Fact] - public async Task Test_CreateIndex_Success() - { - // Arrange - var indexName = "test_index"; - var meilisearchClientMock = new Mock("http://localhost:7700", "masterKey"); - var indexMock = new Mock(meilisearchClientMock.Object, indexName); - var indexes = new List { new IndexResponse { Uid = indexName } }; - - meilisearchClientMock.Setup(c => c.GetAllIndexesAsync(null, null, It.IsAny())).ReturnsAsync(new IndexesResults { Results = new List() }); - meilisearchClientMock.Setup(c => c.CreateIndexAsync(indexName, null, It.IsAny())).Returns(Task.CompletedTask); - meilisearchClientMock.Setup(c => c.GetIndexAsync(indexName, It.IsAny())).ReturnsAsync(indexMock.Object); - indexMock.Setup(i => i.UpdateFilterableAttributesAsync(It.IsAny(), null, It.IsAny())).Returns(Task.CompletedTask); - - // Override the MeilisearchClient - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, null, null, meilisearchClientMock.Object); - - // Act - meiliSearchService.CreateIndex(indexName); - - // Assert - meilisearchClientMock.Verify(c => c.CreateIndexAsync(indexName, null, It.IsAny()), Times.Once); - } - - [Fact] - public async Task Test_DeleteIndex_Success() - { - // Arrange - var indexName = "test_index"; - var meilisearchClientMock = new Mock("http://localhost:7700", "masterKey"); - var indexMock = new Mock(meilisearchClientMock.Object, indexName); - var indexes = new List { new IndexResponse { Uid = indexName } }; - - meilisearchClientMock.Setup(c => c.GetAllIndexesAsync(null, null, It.IsAny())).ReturnsAsync(new IndexesResults { Results = indexes }); - meilisearchClientMock.Setup(c => c.DeleteIndexAsync(indexName, null, It.IsAny())).Returns(Task.CompletedTask); - - // Override the MeilisearchClient - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, null, null, meilisearchClientMock.Object); - - // Act - meiliSearchService.DeleteIndex(indexName); - - // Assert - meilisearchClientMock.Verify(c => c.DeleteIndexAsync(indexName, null, It.IsAny()), Times.Once); - } - - [Fact] - public async Task Test_GetAllIndexes_Success() - { - // Arrange - var indexName = "test_index"; - var meilisearchClientMock = new Mock("http://localhost:7700", "masterKey"); - var indexMock = new Mock(meilisearchClientMock.Object, indexName); - var indexes = new List { new IndexResponse { Uid = indexName } }; - - meilisearchClientMock.Setup(c => c.GetAllIndexesAsync(null, null, It.IsAny())).ReturnsAsync(new IndexesResults { Results = indexes }); - - // Override the MeilisearchClient - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, null, null, meilisearchClientMock.Object); - - // Act - var result = meiliSearchService.GetAllIndexes(); - - // Assert - Assert.Contains(indexName, result); - } - - [Fact] - public void Test_AddDocument_Success() - { - // Arrange - var indexName = "test_index"; - var document = new TestDocument { Id = "1" }; - var documentCollectionMock = new Mock>>(); - - // Override the DocumentCollection - var meiliSearchService = new TestMeiliSearchService(_httpClientMock.Object, _loggerMock.Object, _meiliConfigurationMock.Object, null, null, null, documentCollectionMock.Object); - - // Act - meiliSearchService.AddDocument(indexName, document); - - // Assert - documentCollectionMock.Verify(c => c.Add(It.IsAny>()), Times.Once); - } - - [Fact] - public void Test_Configuration_Dependencies_Success() - { - // Arrange - var httpClient = _httpClientMock.Object; - var logger = _loggerMock.Object; - var meiliConfiguration = _meiliConfigurationMock.Object; - - // Act - var meiliSearchService = new MeiliSearchService(httpClient, logger, meiliConfiguration); - - // Assert - Assert.NotNull(meiliSearchService); - } - - [Fact] - public void Test_GenerateApiKey_Success() - { - // Arrange - var length = 64; - - // Act - var apiKey = MeiliSearchService.GenerateApiKey(length); - - // Assert - Assert.NotNull(apiKey); - Assert.Equal(length, apiKey.Length); - } - - [Fact] - public void Test_Dispose_Success() - { - // Arrange - var httpClientMock = new Mock(); - var processMock = new Mock(); - - // Set the process to the MeiliSearchService - _meiliSearchService.process = processMock.Object; - - // Act - _meiliSearchService.Dispose(); - - // Assert - httpClientMock.Verify(c => c.Dispose(), Times.Never); // HttpClient is disposed in base class - processMock.Verify(p => p.Kill(), Times.Once); - } -} - -// Create a wrapper interface for Process.Start -public interface IProcessWrapper -{ - Process Start(ProcessStartInfo startInfo); -} - -// Create a wrapper class for Process.Start -public class ProcessWrapper : IProcessWrapper -{ - public Process Start(ProcessStartInfo startInfo) - { - return Process.Start(startInfo); - } -} - -// Create a wrapper interface for Process.GetProcessesByName -public interface IProcessStaticWrapper -{ - Process[] GetProcessesByName(string processName); -} - -// Create a wrapper class for Process.GetProcessesByName -public class ProcessStaticWrapper : IProcessStaticWrapper -{ - public Process[] GetProcessesByName(string processName) - { - return Process.GetProcessesByName(processName); - } -} - -// Create a test class to override the GetMeilisearchBinaryName method -public class TestMeiliSearchService : MeiliSearchService -{ - private readonly IProcessWrapper _processWrapper; - private readonly IProcessStaticWrapper _processStaticWrapper; - private readonly MeilisearchClient _meilisearchClient; - private readonly ICollection> _documentCollection; - - public TestMeiliSearchService(HttpClient httpClient, ILogger logger, MeiliSearchConfiguration meiliConfiguration, IProcessWrapper processWrapper = null, IProcessStaticWrapper processStaticWrapper = null, MeilisearchClient meilisearchClient = null, ICollection> documentCollection = null) : base(httpClient, logger, meiliConfiguration) - { - _processWrapper = processWrapper; - _processStaticWrapper = processStaticWrapper; - _meilisearchClient = meilisearchClient; - _documentCollection = documentCollection; - } - - public override async Task StartMeilisearch() - { - var binaryName = GetMeilisearchBinaryName(); - var binaryPath = Path.Combine(AppContext.BaseDirectory, binaryName); - - if (!File.Exists(binaryPath)) - { - Logger.LogError($"Meilisearch binary not found at: {binaryPath}"); - throw new FileNotFoundException($"Could not find Meilisearch binary: {binaryName}"); - } - - // Set execute permissions on Unix-like systems - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - try - { - // Mock the chmod process - //var chmod = Process.Start("chmod", $"+x {binaryPath}"); - //chmod?.WaitForExit(); - } - catch (Exception ex) - { - Logger.LogWarning($"Failed to set execute permissions on binary: {ex.Message}"); - } - } - var host = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? "localhost" - : "127.0.0.1"; - var args = "--http-addr " + host + ":" + MeiliConfiguration.MeiliPort - + " --env development --db-path " - + Path.Combine(AppContext.BaseDirectory, binaryName); - - var processStartInfo = new ProcessStartInfo - { - FileName = binaryPath, - Arguments = args, - UseShellExecute = false, - RedirectStandardOutput = false, - RedirectStandardError = false, - CreateNoWindow = false, - }; - - // Use the mocked Process.Start method - process = _processWrapper.Start(processStartInfo); - await Task.Delay(5000); // Wait for the process to start - Logger.LogInformation($"Started Meilisearch process using binary: {binaryName}"); - } - - public override string GetMeilisearchBinaryName() - { - return "meilisearch-mock"; - } - - public override bool IsMeilisearchRunning() - { - // Mock the Process.GetProcessesByName method - var processName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? "meilisearch-windows" - : "meilisearch"; - var processes = _processStaticWrapper.GetProcessesByName(processName); - return processes.Any(); - } - - public override async Task GetAllIndexesAsync(CancellationToken cancellationToken = default) - { - return _meilisearchClient.GetAllIndexesAsync(null, null, cancellationToken); - } - - public override async Task CreateIndexAsync(string indexName, string primaryKey = null, CancellationToken cancellationToken = default) - { - return _meilisearchClient.CreateIndexAsync(indexName, primaryKey, cancellationToken); - } - - public override async Task DeleteIndexAsync(string indexName, CancellationToken cancellationToken = default) - { - return _meilisearchClient.DeleteIndexAsync(indexName, cancellationToken); - } - - public override async Task GetIndexAsync(string indexName, CancellationToken cancellationToken = default) - { - return _meilisearchClient.GetIndexAsync(indexName, cancellationToken); - } - - private ILogger Logger - { - get { return _logger; } - } - - private MeiliSearchConfiguration MeiliConfiguration - { - get { return _meiliConfiguration; } - } - - private string ApiKey - { - get { return _apiKey; } - } - - protected override ObservableCollection> DocumentCollection - { - get - { - return _documentCollection as ObservableCollection>; - } - } - - protected virtual void Dispose(bool disposing) - { - //base.Dispose(disposing); - } -} - -public class TestDocument : IDocument -{ - public new string Id { get; set; } -} diff --git a/meilisearch.NET.Tests/UnitTest1.cs b/meilisearch.NET.Tests/UnitTest1.cs deleted file mode 100644 index 6e6593b..0000000 --- a/meilisearch.NET.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace meilisearch.NET.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} \ No newline at end of file diff --git a/meilisearch.NET.Tests/meilisearch.NET.Tests.csproj b/meilisearch.NET.Tests/meilisearch.NET.Tests.csproj deleted file mode 100644 index cdf689f..0000000 --- a/meilisearch.NET.Tests/meilisearch.NET.Tests.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - - - - - - - - - - - - - diff --git a/meilisearch.NET.sln b/meilisearch.NET.sln index 1eca3fa..147cf43 100644 --- a/meilisearch.NET.sln +++ b/meilisearch.NET.sln @@ -4,8 +4,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "meilisearch.NET", "meilisea EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "meilisearch.NET.example", "meilisearch.NET.example\meilisearch.NET.example.csproj", "{E753BBD6-6ADF-4DD4-8822-7279CD55DF58}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "meilisearch.NET.Tests", "meilisearch.NET.Tests\meilisearch.NET.Tests.csproj", "{D69D6DD2-1838-495A-A1CC-4318DCA608E3}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,9 +18,5 @@ Global {E753BBD6-6ADF-4DD4-8822-7279CD55DF58}.Debug|Any CPU.Build.0 = Debug|Any CPU {E753BBD6-6ADF-4DD4-8822-7279CD55DF58}.Release|Any CPU.ActiveCfg = Release|Any CPU {E753BBD6-6ADF-4DD4-8822-7279CD55DF58}.Release|Any CPU.Build.0 = Release|Any CPU - {D69D6DD2-1838-495A-A1CC-4318DCA608E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D69D6DD2-1838-495A-A1CC-4318DCA608E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D69D6DD2-1838-495A-A1CC-4318DCA608E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D69D6DD2-1838-495A-A1CC-4318DCA608E3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal