Skip to content

Commit 0989606

Browse files
committed
(#1308) Add tests
1 parent 2b51384 commit 0989606

File tree

11 files changed

+287
-66
lines changed

11 files changed

+287
-66
lines changed

src/Infra/Lanceur.Infra.Win32/Services/SteamLibraryService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public partial class SteamLibraryService : ISteamLibraryService
1313
{
1414
#region Fields
1515

16-
private DateTime _lastCacheUpdate = DateTime.Now;
16+
private DateTime _lastCacheUpdate = DateTime.MinValue;
1717

1818
private readonly ILogger<SteamLibraryService> _logger;
1919
private readonly IMemoryCache _memoryCache;
@@ -79,6 +79,7 @@ private IEnumerable<string> GetLibraryPaths()
7979
entry => {
8080
entry.AbsoluteExpirationRelativeToNow = 10.Seconds();
8181
var libraries = new List<string>();
82+
8283
foreach (Match m in KeyValuePattern().Matches(File.ReadAllText(vdf)))
8384
{
8485
_logger.LogDebug("Found library path: {LibraryPath}", m.Groups[1].Value);

src/Infra/Lanceur.Infra/Stores/EverythingStore.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public class EverythingStore : StoreBase, IStoreService
1818

1919
private readonly IEverythingApi _everythingApi;
2020
private readonly ILogger<EverythingStore> _logger;
21-
private readonly ISection<StoreSection> _settings;
2221

2322
#endregion
2423

@@ -28,13 +27,11 @@ public EverythingStore(
2827
IStoreOrchestrationFactory orchestrationFactory,
2928
ILogger<EverythingStore> logger,
3029
IEverythingApi everythingApi,
31-
ISection<StoreSection> settings,
3230
ISection<StoreSection> storeSettings
3331
) : base(orchestrationFactory, storeSettings)
3432
{
3533
_logger = logger;
3634
_everythingApi = everythingApi;
37-
_settings = settings;
3835
}
3936

4037
#endregion
@@ -59,7 +56,7 @@ public IEnumerable<QueryResult> Search(Cmdline cmdline)
5956
return DisplayQueryResult.SingleFromResult("Enter text to search with Everything tool...");
6057
}
6158

62-
var query = $"{cmdline.Parameters} {_settings.Value.EverythingQuerySuffix}";
59+
var query = $"{cmdline.Parameters} {StoreSettings.Value.EverythingQuerySuffix}";
6360
_logger.LogTrace("Everything query: {Query}", query);
6461

6562
var result = _everythingApi.Search(query);

src/Infra/Lanceur.Infra/Stores/StoreBase.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,21 @@ protected StoreBase(
1515
IStoreOrchestrationFactory orchestrationFactory,
1616
ISection<StoreSection> storeSettings)
1717
{
18+
ArgumentNullException.ThrowIfNull(orchestrationFactory);
19+
ArgumentNullException.ThrowIfNull(storeSettings);
20+
1821
StoreSettings = storeSettings;
19-
StoreOrchestrationFactory
20-
= orchestrationFactory ??
21-
throw new ArgumentException(
22-
$"The {typeof(IStoreOrchestrationFactory)} should be configured in the IOC container."
23-
);
22+
StoreOrchestrationFactory = orchestrationFactory;
2423
}
2524

2625
#endregion
2726

2827
#region Properties
2928

3029
/// <summary>
31-
/// Returns the default shortcut defined for the macro. If no shortcut defined, then empty string
32-
/// is returned
30+
/// Returns the effective shortcut for this store. If a user-defined override is configured,
31+
/// it takes precedence over the default shortcut defined via <see cref="StoreAttribute" />.
32+
/// Returns an empty string if neither is defined.
3333
/// </summary>
3434
protected string DefaultShortcut
3535
{
Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Web.Bookmarks;
22
using Everything.Wrapper;
33
using Lanceur.Core;
4+
using Lanceur.Core.Configuration;
45
using Lanceur.Core.Configuration.Configurations;
56
using Lanceur.Core.Configuration.Sections;
67
using Lanceur.Core.Repositories;
@@ -14,39 +15,50 @@ namespace Lanceur.Tests.Tools.Extensions;
1415

1516
public static class StoreExtensions
1617
{
17-
extension(IServiceCollection serviceCollection)
18-
{
19-
#region Methods
18+
#region Methods
2019

21-
public IServiceCollection AddStoreServicesConfiguration(ApplicationSettings? configuration = null)
22-
{
23-
serviceCollection
24-
.AddConfigurationSections()
25-
.AddMockSingleton<IConfigurationFacade>((_, i) => {
26-
i.Application.Returns(
27-
configuration ??
28-
new ApplicationSettings { Caching = new CachingSection(0, 0), Stores = new StoreSection() }
29-
);
30-
return i;
31-
}
32-
);
33-
return serviceCollection;
34-
}
20+
public static IServiceCollection AddStoreServicesConfiguration(
21+
this IServiceCollection serviceCollection,
22+
ApplicationSettings? configuration = null)
23+
{
24+
serviceCollection
25+
.AddConfigurationSections()
26+
.AddMockSingleton<IConfigurationFacade>((_, i) => {
27+
i.Application.Returns(
28+
configuration ??
29+
new ApplicationSettings { Caching = new CachingSection(0, 0), Stores = new StoreSection() }
30+
);
31+
return i;
32+
}
33+
);
34+
return serviceCollection;
35+
}
3536

36-
public IServiceCollection AddStoreServicesMockContext()
37-
{
38-
serviceCollection
39-
.AddMockSingleton<IAliasRepository>()
40-
.AddMockSingleton<IFeatureFlagService>()
41-
.AddMockSingleton<IBookmarkRepositoryFactory>()
42-
.AddMockSingleton<ICalculatorService>()
43-
.AddMockSingleton<AssemblySource>()
44-
.AddMockSingleton<ISteamLibraryService>()
45-
.AddMockSingleton<IAliasManagementService>()
46-
.AddMockSingleton<IEverythingApi>();
47-
return serviceCollection;
48-
}
37+
public static IServiceCollection AddStoreServicesMockContext(
38+
this IServiceCollection serviceCollection,
39+
Func<IServiceProvider, ISection<StoreSection>, ISection<StoreSection>> configurator)
40+
{
41+
serviceCollection
42+
.AddMockSingleton<IAliasRepository>()
43+
.AddMockSingleton<IFeatureFlagService>()
44+
.AddMockSingleton<IBookmarkRepositoryFactory>()
45+
.AddMockSingleton<ICalculatorService>()
46+
.AddMockSingleton<AssemblySource>()
47+
.AddMockSingleton<ISteamLibraryService>()
48+
.AddMockSingleton<IAliasManagementService>()
49+
.AddMockSingleton<IEverythingApi>()
50+
.AddMockSingleton(configurator);
51+
return serviceCollection;
52+
}
4953

50-
#endregion
54+
public static IServiceCollection AddStoreServicesMockContext(this IServiceCollection serviceCollection)
55+
{
56+
serviceCollection.AddStoreServicesMockContext((_, i) => {
57+
i.Value.Returns(new StoreSection());
58+
return i;
59+
});
60+
return serviceCollection;
5161
}
62+
63+
#endregion
5264
}

src/Tests/Lanceur.Tests.Tools/ViewModelTester.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ out TViewModel viewModel
4747
.AddSingleton<IEnigma, Enigma>()
4848
.AddSingleton(new LoggingLevelSwitch(LogEventLevel.Verbose))
4949
.AddReservedAliases(typeof(AddAlias))
50+
.AddMockSingleton<IStoreShortcutService>()
5051
.AddDatabase(connectionManager);
5152

5253
var serviceProvider = ConfigureServices(serviceCollection, visitors).BuildServiceProvider();

src/Tests/Lanceur.Tests/Services/SearchServiceTest.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Data.SQLite;
33
using Dapper;
44
using Lanceur.Core;
5+
using Lanceur.Core.Configuration;
6+
using Lanceur.Core.Configuration.Sections;
57
using Lanceur.Core.Managers;
68
using Lanceur.Core.Models;
79
using Lanceur.Core.Repositories;
@@ -113,7 +115,8 @@ public async Task When_macro_is_misconfigured_Then_it_is_excluded_from_result()
113115
.AddSingleton<IDbConnection, SQLiteConnection>()
114116
.AddSingleton<SearchService>()
115117
.AddSingleton<AssemblySource>()
116-
.AddSingleton<IDbActionFactory, DbActionFactory>();
118+
.AddSingleton<IDbActionFactory, DbActionFactory>()
119+
.AddStoreServicesMockContext();
117120

118121
serviceCollection.TryAddEnumerable(ServiceDescriptor.Singleton<IStoreService, AliasStore>());
119122
serviceCollection.AddTestOutputHelper(OutputHelper);
@@ -269,8 +272,9 @@ public async Task When_there_is_result_with_exact_match_Then_it_is_moved_on_top_
269272
.Returns(true);
270273
return orchestrator;
271274
}
272-
);
273-
sc.TryAddEnumerable(ServiceDescriptor.Singleton<IStoreService, AliasStore>());
275+
)
276+
.AddStoreServicesConfiguration()
277+
.TryAddEnumerable(ServiceDescriptor.Singleton<IStoreService, AliasStore>());
274278

275279
var serviceProvider = sc.BuildServiceProvider();
276280

src/Tests/Lanceur.Tests/Stores/IoCForStoresShould.cs

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Everything.Wrapper;
12
using Lanceur.Core.Configuration;
23
using Lanceur.Core.Configuration.Configurations;
34
using Lanceur.Core.Configuration.Sections;
@@ -14,6 +15,7 @@
1415
using Lanceur.Tests.Tools.SQL;
1516
using Lanceur.Ui.Core.Extensions;
1617
using Microsoft.Extensions.DependencyInjection;
18+
using NSubstitute;
1719
using Shouldly;
1820
using Xunit;
1921

@@ -52,7 +54,7 @@ public void RegisterAllStores()
5254
[Theory]
5355
[InlineData(null, "pp hello world")] // null override, then use the default one
5456
[InlineData("^pp.*", ": hello world")]
55-
public void UseDefaultShortcutWhenNoOverride(string aliasOverride, string cmdlineString)
57+
public void UseDefaultShortcutWhenNoOverride(string? aliasOverride, string cmdlineString)
5658
{
5759
// arrange
5860
var cfgOverride = aliasOverride is null
@@ -77,9 +79,22 @@ public void UseDefaultShortcutWhenNoOverride(string aliasOverride, string cmdlin
7779
.AddSingleton<IStoreService, EverythingStore>()
7880
.AddSingleton<IStoreOrchestrationFactory, StoreOrchestrationFactory>()
7981
.AddSingleton<ISearchServiceOrchestrator, SearchServiceOrchestrator>()
80-
.AddStoreServicesMockContext()
8182
.AddStoreServicesConfiguration(cfgOverride)
8283
.AddTestOutputHelper(OutputHelper)
84+
.AddStoreServicesMockContext((_, i) => {
85+
i.Value.Returns(new StoreSection
86+
{
87+
StoreShortcuts =
88+
[
89+
new StoreShortcut
90+
{
91+
AliasOverride = aliasOverride,
92+
StoreType = typeof(EverythingStore).FullName
93+
}
94+
]
95+
});
96+
return i;
97+
})
8398
.BuildServiceProvider();
8499

85100
// act
@@ -89,14 +104,16 @@ public void UseDefaultShortcutWhenNoOverride(string aliasOverride, string cmdlin
89104
var orchestrator = serviceProvider.GetService<ISearchServiceOrchestrator>()!;
90105

91106
// assert
107+
OutputHelper.WriteLine($"Alive pattern: '{store.StoreOrchestration.AlivePattern}'");
108+
OutputHelper.WriteLine($"Cmdline : {cmdlineString}");
92109
orchestrator.IsAlive(store, Cmdline.Parse(cmdlineString))
93110
.ShouldBeFalse();
94111
}
95112

96113
[Theory]
97114
[InlineData(null, ": hello world")] // null override, then use the default one
98115
[InlineData("^pp.*", "pp hello world")]
99-
public void UseOverridenShortcutWhenConfigured(string aliasOverride, string cmdlineString)
116+
public void UseOverridenShortcutWhenConfigured(string? aliasOverride, string cmdlineString)
100117
{
101118
// arrange
102119
var cfgOverride = aliasOverride is null
@@ -121,7 +138,17 @@ public void UseOverridenShortcutWhenConfigured(string aliasOverride, string cmdl
121138
.AddSingleton<IStoreService, EverythingStore>()
122139
.AddSingleton<IStoreOrchestrationFactory, StoreOrchestrationFactory>()
123140
.AddSingleton<ISearchServiceOrchestrator, SearchServiceOrchestrator>()
124-
.AddStoreServicesMockContext()
141+
.AddStoreServicesMockContext((_, i) => {
142+
i.Value.Returns(new StoreSection()
143+
{
144+
StoreShortcuts = [new StoreShortcut
145+
{
146+
StoreType = typeof(EverythingStore).FullName,
147+
AliasOverride = aliasOverride
148+
}]
149+
});
150+
return i;
151+
})
125152
.AddStoreServicesConfiguration(cfgOverride)
126153
.BuildServiceProvider();
127154

@@ -157,19 +184,23 @@ public void UseOverridenShortcutWhenUpdated()
157184
var orchestrator = serviceProvider.GetService<ISearchServiceOrchestrator>()!;
158185
var configuration = serviceProvider.GetService<IConfigurationFacade>()!;
159186

160-
// At this point, there's no configuration, we used the default config (hardcoded)
161-
orchestrator.IsAlive(store, Cmdline.Parse(cmdlineString1)).ShouldBeTrue("Default values should be used");
162-
163-
// Let's update the configuration and check whether it is taken into account
164-
UpdateConfiguration(aliasOverride1);
165-
orchestrator.IsAlive(store, Cmdline.Parse(cmdlineString2))
166-
.ShouldBeTrue("When updating from default values to new value");
167-
168-
// Let's do this again to be sure the update can be done multiple times
169-
UpdateConfiguration(aliasOverride2);
170-
orchestrator.IsAlive(store, Cmdline.Parse(cmdlineString3))
171-
.ShouldBeTrue("When updating from some values to updated values");
172-
187+
orchestrator.ShouldSatisfyAllConditions(
188+
o =>
189+
// "At this point, there's no configuration, we used the default config (hardcoded)"
190+
o.IsAlive(store, Cmdline.Parse(cmdlineString1))
191+
.ShouldBeTrue("Default values should be used"),
192+
o => {
193+
// Let's update the configuration and check whether it is taken into account
194+
UpdateConfiguration(aliasOverride1);
195+
o.IsAlive(store, Cmdline.Parse(cmdlineString2))
196+
.ShouldBeTrue("When updating from default values to new value");
197+
},
198+
o => {
199+
// Let's do this again to be sure the update can be done multiple times
200+
UpdateConfiguration(aliasOverride2);
201+
o.IsAlive(store, Cmdline.Parse(cmdlineString3))
202+
.ShouldBeTrue("When updating from some values to updated values");
203+
});
173204
return;
174205

175206
IServiceProvider ConfigureServices()
@@ -180,8 +211,7 @@ IServiceProvider ConfigureServices()
180211
.AddSingleton<IStoreService, EverythingStore>()
181212
.AddSingleton<IStoreOrchestrationFactory, StoreOrchestrationFactory>()
182213
.AddSingleton<ISearchServiceOrchestrator, SearchServiceOrchestrator>()
183-
.AddStoreServicesMockContext()
184-
.AddTestOutputHelper(OutputHelper);
214+
.AddMockSingleton<IEverythingApi>(); // Real ISection<StoreSection> needed — don't use AddStoreServicesMockContext()
185215

186216
serviceCollection.AddConfiguration() // Real configuration facility (not mocked)
187217
.AddConfigurationSections()
@@ -193,7 +223,11 @@ void UpdateConfiguration(string aliasOverride)
193223
{
194224
configuration.Application.Stores.StoreShortcuts =
195225
[
196-
new StoreShortcut { StoreType = typeof(EverythingStore).ToString(), AliasOverride = aliasOverride }
226+
new StoreShortcut
227+
{
228+
StoreType = typeof(EverythingStore).ToString(),
229+
AliasOverride = aliasOverride
230+
}
197231
];
198232
configuration.Save();
199233
}

src/Tests/Lanceur.Tests/Stores/ReservedKeywordsStoreTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Web.Bookmarks;
22
using Lanceur.Core;
3+
using Lanceur.Core.Configuration;
34
using Lanceur.Core.Configuration.Configurations;
5+
using Lanceur.Core.Configuration.Sections;
46
using Lanceur.Core.Managers;
57
using Lanceur.Core.Models;
68
using Lanceur.Core.Repositories;
@@ -52,6 +54,7 @@ private ReservedAliasStore GetStore(IAliasRepository aliasRepository, Type? type
5254
return i;
5355
}
5456
)
57+
.AddMockSingleton<ISection<StoreSection>>()
5558
.AddSingleton<ReservedAliasStore>()
5659
.AddReservedAliases(type)
5760
.AddMockSingleton<IUserDialogueService>()

src/Tests/Lanceur.Tests/Stores/SteamGameStoreTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using Lanceur.Core.Configuration;
2+
using Lanceur.Core.Configuration.Sections;
13
using Lanceur.Core.Managers;
24
using Lanceur.Core.Models;
35
using Lanceur.Core.Services;
@@ -33,6 +35,7 @@ private SteamGameStore GetStore(ISteamLibraryService steamService, IAliasManagem
3335
.AddSingleton(steamService)
3436
.AddSingleton(managementService)
3537
.AddSingleton<SteamGameStore>()
38+
.AddMockSingleton<ISection<StoreSection>>()
3639
.AddMockSingleton<IFeatureFlagService>((_, i)=> {
3740
i.IsEnabled(Arg.Any<string>()).Returns(true);
3841
return i;

0 commit comments

Comments
 (0)