diff --git a/.editorconfig b/.editorconfig
index 64ad963b34..f2ea6175b6 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -37,22 +37,37 @@ trim_trailing_whitespace = true
tab_width = 4
# New line preferences
csharp_new_line_before_open_brace = all
+csharp_new_line_before_open_brace_for_methods = true
+csharp_new_line_before_open_brace_for_control_blocks = true
+csharp_preserve_single_line_statements = false
+csharp_style_allow_embedded_statements_on_same_line_experimental = false
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
csharp_new_line_within_query_expression_clauses = true
csharp_wrap_before_eq = false
place_attribute_on_same_line = "never"
# csharp_style_namespace_declarations = file_scoped:warning
+# https://dotnettips.wordpress.com/2023/06/27/microsoft-net-code-analysis-always-add-braces-in-c/
+dotnet_diagnostic.IDE0011.severity = warning
+csharp_prefer_braces = true:warning
+dotnet_diagnostic.SA1500.severity = warning
+dotnet_diagnostic.SA1503.severity = warning
+dotnet_diagnostic.SA1520.severity = warning
+
+
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
+csharp_indent_case_contents_when_block = false
+csharp_space_after_cast = true
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
diff --git a/starsky/starsky.foundation.database/Query/Query.cs b/starsky/starsky.foundation.database/Query/Query.cs
index d27ab6be29..f0fe289d76 100644
--- a/starsky/starsky.foundation.database/Query/Query.cs
+++ b/starsky/starsky.foundation.database/Query/Query.cs
@@ -49,12 +49,19 @@ public Query(ApplicationDbContext context,
/// FileIndex-objects with database data
public FileIndexItem? GetObjectByFilePath(string filePath)
{
- if ( filePath != "/" ) filePath = PathHelper.RemoveLatestSlash(filePath);
+ if ( filePath != "/" )
+ {
+ filePath = PathHelper.RemoveLatestSlash(filePath);
+ }
FileIndexItem? LocalQuery(ApplicationDbContext context)
{
var item = context.FileIndex.FirstOrDefault(p => p.FilePath == filePath);
- if ( item != null ) item.Status = FileIndexItem.ExifStatus.Ok;
+ if ( item != null )
+ {
+ item.Status = FileIndexItem.ExifStatus.Ok;
+ }
+
return item;
}
@@ -85,7 +92,11 @@ public Query(ApplicationDbContext context,
_cache.TryGetValue(
GetObjectByFilePathAsyncCacheName(filePath), out var data) )
{
- if ( !( data is FileIndexItem fileIndexItem ) ) return null;
+ if ( !( data is FileIndexItem fileIndexItem ) )
+ {
+ return null;
+ }
+
fileIndexItem.Status = FileIndexItem.ExifStatus.OkAndSame;
return fileIndexItem;
}
@@ -95,7 +106,9 @@ public Query(ApplicationDbContext context,
// cache code:
if ( cacheTime == null || _appSettings.AddMemoryCache != true || result == null )
+ {
return result;
+ }
SetGetObjectByFilePathCache(filePath, result.Clone(), cacheTime);
@@ -120,19 +133,25 @@ public void SetGetObjectByFilePathCache(string filePath,
public async Task GetSubPathByHashAsync(string fileHash)
{
// The CLI programs uses no cache
- if ( !IsCacheEnabled() || _cache == null ) return await QueryGetItemByHashAsync(fileHash);
+ if ( !IsCacheEnabled() || _cache == null )
+ {
+ return await QueryGetItemByHashAsync(fileHash);
+ }
// Return values from IMemoryCache
var queryHashListCacheName = CachingDbName("hashList", fileHash);
// if result is not null return cached value
if ( _cache.TryGetValue(queryHashListCacheName, out var cachedSubPath)
- && !string.IsNullOrEmpty(( string? )cachedSubPath) ) return ( string )cachedSubPath;
+ && !string.IsNullOrEmpty(( string? ) cachedSubPath) )
+ {
+ return ( string ) cachedSubPath;
+ }
cachedSubPath = await QueryGetItemByHashAsync(fileHash);
_cache.Set(queryHashListCacheName, cachedSubPath, new TimeSpan(48, 0, 0));
- return ( string? )cachedSubPath;
+ return ( string? ) cachedSubPath;
}
///
@@ -141,11 +160,17 @@ public void SetGetObjectByFilePathCache(string filePath,
/// base32 fileHash
public void ResetItemByHash(string? fileHash)
{
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return;
+ }
var queryCacheName = CachingDbName("hashList", fileHash);
- if ( _cache.TryGetValue(queryCacheName, out _) ) _cache.Remove(queryCacheName);
+ if ( _cache.TryGetValue(queryCacheName, out _) )
+ {
+ _cache.Remove(queryCacheName);
+ }
}
///
@@ -165,7 +190,9 @@ async Task LocalQuery(ApplicationDbContext context, FileIndexItem fileIndexItem)
CacheUpdateItem(new List { updateStatusContent.Clone() });
if ( _appSettings.Verbose == true )
// Ef core changes debug
+ {
_logger.LogDebug(context.ChangeTracker.DebugView.LongView);
+ }
// object cache path is used to avoid updates
SetGetObjectByFilePathCache(fileIndexItem.FilePath!, updateStatusContent,
@@ -204,7 +231,11 @@ await RetryQueryUpdateSaveChangesAsync(updateStatusContent, e,
{
// Skip if Duplicate entry
// MySqlConnector.MySqlException (0x80004005): Duplicate entry for key 'PRIMARY'
- if ( !exception.Message.Contains("Duplicate") ) throw;
+ if ( !exception.Message.Contains("Duplicate") )
+ {
+ throw;
+ }
+
_logger.LogError(exception,
$"[UpdateItemAsync] Skipped MySqlException Duplicate entry for key {updateStatusContent.FilePath}");
}
@@ -221,12 +252,16 @@ await RetryQueryUpdateSaveChangesAsync(updateStatusContent, e,
public async Task> UpdateItemAsync(
List updateStatusContentList)
{
- if ( updateStatusContentList.Count == 0 ) return new List();
+ if ( updateStatusContentList.Count == 0 )
+ {
+ return new List();
+ }
async Task> LocalQuery(DbContext context,
List fileIndexItems)
{
foreach ( var item in fileIndexItems )
+ {
try
{
context.Attach(item).State = EntityState.Modified;
@@ -236,11 +271,14 @@ async Task> LocalQuery(DbContext context,
// System.InvalidOperationException: The property 'FileIndexItem.Id' has a temporary value while attempting to change the entity's state to 'Modified'
// Issue #994
}
+ }
await context.SaveChangesAsync();
foreach ( var item in fileIndexItems )
+ {
context.Attach(item).State = EntityState.Detached;
+ }
CacheUpdateItem(fileIndexItems);
return fileIndexItems;
@@ -288,14 +326,19 @@ async Task> LocalQuery(DbContext context,
/// items to update
public void CacheUpdateItem(List updateStatusContent)
{
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return;
+ }
var skippedCacheItems = new HashSet();
foreach ( var item in updateStatusContent.ToList() )
{
if ( item.Status == FileIndexItem.ExifStatus.OkAndSame ||
item.Status == FileIndexItem.ExifStatus.Default )
+ {
item.Status = FileIndexItem.ExifStatus.Ok;
+ }
// ToList() > Collection was modified; enumeration operation may not execute.
var queryCacheName = CachingDbName(nameof(FileIndexItem),
@@ -309,7 +352,7 @@ public void CacheUpdateItem(List updateStatusContent)
}
objectFileFolders ??= new List();
- var displayFileFolders = ( List )objectFileFolders;
+ var displayFileFolders = ( List ) objectFileFolders;
// make it a list to avoid enum errors
displayFileFolders = displayFileFolders.ToList();
@@ -317,12 +360,16 @@ public void CacheUpdateItem(List updateStatusContent)
var obj = displayFileFolders.Find(p => p.FilePath == item.FilePath);
if ( obj != null )
// remove add again
+ {
displayFileFolders.Remove(obj);
+ }
if ( item.Status ==
FileIndexItem.ExifStatus.Ok ) // ExifStatus.default is already changed
// Add here item to cached index
+ {
displayFileFolders.Add(item);
+ }
// make it a list to avoid enum errors
displayFileFolders = displayFileFolders.ToList();
@@ -334,8 +381,10 @@ public void CacheUpdateItem(List updateStatusContent)
}
if ( skippedCacheItems.Count >= 1 && _appSettings.Verbose == true )
+ {
_logger.LogInformation(
$"[CacheUpdateItem] skipped: {string.Join(", ", skippedCacheItems)}");
+ }
}
///
@@ -343,11 +392,19 @@ public void CacheUpdateItem(List updateStatusContent)
/// This Does remove a SINGLE item from the cache NOT from the database
///
///
+ [SuppressMessage("ReSharper",
+ "S4136: All 'RemoveCacheItem' method overloads should be adjacent.")]
public void RemoveCacheItem(List updateStatusContent)
{
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return;
+ }
- foreach ( var item in updateStatusContent.ToList() ) RemoveCacheItem(item);
+ foreach ( var item in updateStatusContent.ToList() )
+ {
+ RemoveCacheItem(item);
+ }
}
///
@@ -357,11 +414,17 @@ public void RemoveCacheItem(List updateStatusContent)
public bool RemoveCacheParentItem(string directoryName)
{
// Add protection for disabled caching
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return false;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return false;
+ }
var queryCacheName = CachingDbName(nameof(FileIndexItem),
PathHelper.RemoveLatestSlash(directoryName.Clone().ToString()!));
- if ( !_cache.TryGetValue(queryCacheName, out _) ) return false;
+ if ( !_cache.TryGetValue(queryCacheName, out _) )
+ {
+ return false;
+ }
_cache.Remove(queryCacheName);
return true;
@@ -375,7 +438,10 @@ public bool RemoveCacheParentItem(string directoryName)
public bool AddCacheParentItem(string directoryName, List items)
{
// Add protection for disabled caching
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return false;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return false;
+ }
var queryCacheName = CachingDbName(nameof(FileIndexItem),
PathHelper.RemoveLatestSlash(directoryName.Clone().ToString()!));
@@ -402,7 +468,11 @@ async Task LocalDefaultQuery()
async Task LocalQuery(ApplicationDbContext context)
{
// only in test case fileIndex is null
- if ( context.FileIndex != null ) await context.FileIndex.AddAsync(fileIndexItem);
+ if ( context.FileIndex != null )
+ {
+ await context.FileIndex.AddAsync(fileIndexItem);
+ }
+
await context.SaveChangesAsync();
// Fix for: The instance of entity type 'Item' cannot be tracked because
// another instance with the same key value for {'Id'} is already being tracked
@@ -462,7 +532,9 @@ public async Task> AddParentItemsAsync(string subPath)
var toAddList = new List();
// ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
foreach ( var pathShouldExist in pathListShouldExist )
+ {
if ( !indexItems.Select(p => p.FilePath).Contains(pathShouldExist) )
+ {
toAddList.Add(new FileIndexItem(pathShouldExist)
{
IsDirectory = true,
@@ -471,6 +543,8 @@ public async Task> AddParentItemsAsync(string subPath)
Software = pathShouldExist == "/" ? "Root object" : string.Empty,
Status = FileIndexItem.ExifStatus.Ok
});
+ }
+ }
await AddRangeAsync(toAddList);
return toAddList;
@@ -492,7 +566,11 @@ internal static string GetObjectByFilePathAsyncCacheName(string subPath)
private async Task GetObjectByFilePathQueryAsync(
string filePath)
{
- if ( filePath != "/" ) filePath = PathHelper.RemoveLatestSlash(filePath);
+ if ( filePath != "/" )
+ {
+ filePath = PathHelper.RemoveLatestSlash(filePath);
+ }
+
var paths = new List { filePath };
return ( await GetObjectsByFilePathQueryAsync(paths) )
.FirstOrDefault();
@@ -528,7 +606,11 @@ internal static string GetObjectByFilePathAsyncCacheName(string subPath)
internal static string CachingDbName(string functionName, string? singleItemDbPath)
{
// when is nothing assume its the home item
- if ( string.IsNullOrWhiteSpace(singleItemDbPath) ) singleItemDbPath = "/";
+ if ( string.IsNullOrWhiteSpace(singleItemDbPath) )
+ {
+ singleItemDbPath = "/";
+ }
+
// For creating an unique name: DetailView_/2018/01/1.jpg
var uniqueSingleDbCacheNameBuilder = new StringBuilder();
uniqueSingleDbCacheNameBuilder.Append(functionName + "_" + singleItemDbPath);
@@ -560,7 +642,11 @@ async Task LocalRetrySaveChangesAsyncQuery()
// https://go.microsoft.com/fwlink/?linkid=2097913
await Task.Delay(delay);
var context = new InjectServiceScope(_scopeFactory).Context();
- if ( context == null! ) throw new AggregateException("Query Context is null");
+ if ( context == null! )
+ {
+ throw new AggregateException("Query Context is null");
+ }
+
context.Attach(updateStatusContent).State = EntityState.Modified;
await context.SaveChangesAsync();
context.Attach(updateStatusContent).State = EntityState.Unchanged;
@@ -605,7 +691,11 @@ async Task LocalRetrySaveChangesAsyncQuery()
/// true when enabled
internal bool IsCacheEnabled()
{
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return false;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return false;
+ }
+
return true;
}
@@ -619,17 +709,26 @@ internal bool IsCacheEnabled()
internal void AddCacheItem(FileIndexItem updateStatusContent)
{
// If cache is turned of
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return;
+ }
var queryCacheName = CachingDbName(nameof(FileIndexItem),
updateStatusContent.ParentDirectory!);
- if ( !_cache.TryGetValue(queryCacheName, out var objectFileFolders) ) return;
+ if ( !_cache.TryGetValue(queryCacheName, out var objectFileFolders) )
+ {
+ return;
+ }
objectFileFolders ??= new List();
- var displayFileFolders = ( List )objectFileFolders;
+ var displayFileFolders = ( List ) objectFileFolders;
- if ( updateStatusContent.FilePath == "/" ) return;
+ if ( updateStatusContent.FilePath == "/" )
+ {
+ return;
+ }
displayFileFolders.Add(updateStatusContent);
// Order by filename
@@ -647,15 +746,21 @@ internal void AddCacheItem(FileIndexItem updateStatusContent)
public void RemoveCacheItem(FileIndexItem updateStatusContent)
{
// Add protection for disabled caching
- if ( _cache == null || _appSettings.AddMemoryCache == false ) return;
+ if ( _cache == null || _appSettings.AddMemoryCache == false )
+ {
+ return;
+ }
var queryCacheName = CachingDbName(nameof(FileIndexItem),
updateStatusContent.ParentDirectory!);
- if ( !_cache.TryGetValue(queryCacheName, out var objectFileFolders) ) return;
+ if ( !_cache.TryGetValue(queryCacheName, out var objectFileFolders) )
+ {
+ return;
+ }
objectFileFolders ??= new List();
- var displayFileFolders = ( List )objectFileFolders;
+ var displayFileFolders = ( List ) objectFileFolders;
// Order by filename
displayFileFolders = displayFileFolders
diff --git a/starsky/starsky/Controllers/AllowedTypesController.cs b/starsky/starsky/Controllers/AllowedTypesController.cs
index b60eb91e9f..0882b6ccd4 100644
--- a/starsky/starsky/Controllers/AllowedTypesController.cs
+++ b/starsky/starsky/Controllers/AllowedTypesController.cs
@@ -5,61 +5,69 @@
using starsky.foundation.platform.Helpers;
using starsky.project.web.Helpers;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class AllowedTypesController : Controller
{
- [Authorize]
- public sealed class AllowedTypesController : Controller
+ ///
+ /// A (string) list of allowed MIME-types ExtensionSyncSupportedList
+ ///
+ /// Json list
+ /// list
+ /// please login first
+ [HttpGet("/api/allowed-types/mimetype/sync")]
+ [ProducesResponseType(typeof(HashSet), 200)]
+ [Produces("application/json")]
+ public IActionResult AllowedTypesMimetypeSync()
{
- ///
- /// A (string) list of allowed MIME-types ExtensionSyncSupportedList
- ///
- /// Json list
- /// list
- /// please login first
- [HttpGet("/api/allowed-types/mimetype/sync")]
- [ProducesResponseType(typeof(HashSet), 200)]
- [Produces("application/json")]
- public IActionResult AllowedTypesMimetypeSync()
- {
- var mimeTypes = ExtensionRolesHelper.ExtensionSyncSupportedList
- .Select(MimeHelper.GetMimeType).ToHashSet();
- return Json(mimeTypes);
- }
+ var mimeTypes = ExtensionRolesHelper.ExtensionSyncSupportedList
+ .Select(MimeHelper.GetMimeType).ToHashSet();
+ return Json(mimeTypes);
+ }
- ///
- /// A (string) list of allowed ExtensionThumbSupportedList MimeTypes
- ///
- /// Json list
- /// list
- /// please login first
- [HttpGet("/api/allowed-types/mimetype/thumb")]
- [ProducesResponseType(typeof(HashSet), 200)]
- [Produces("application/json")]
- public IActionResult AllowedTypesMimetypeSyncThumb()
+ ///
+ /// A (string) list of allowed ExtensionThumbSupportedList MimeTypes
+ ///
+ /// Json list
+ /// list
+ /// please login first
+ [HttpGet("/api/allowed-types/mimetype/thumb")]
+ [ProducesResponseType(typeof(HashSet), 200)]
+ [Produces("application/json")]
+ public IActionResult AllowedTypesMimetypeSyncThumb()
+ {
+ var mimeTypes = ExtensionRolesHelper.ExtensionThumbSupportedList
+ .Select(MimeHelper.GetMimeType).ToHashSet();
+ return Json(mimeTypes);
+ }
+
+ ///
+ /// Check if IsExtensionThumbnailSupported
+ ///
+ /// Json list
+ /// the name with extension and no parent path
+ /// is supported
+ /// the extenstion from the filename is not supported to generate thumbnails
+ /// please log in first
+ [HttpGet("/api/allowed-types/thumb")]
+ [ProducesResponseType(typeof(bool), 200)]
+ [ProducesResponseType(typeof(bool), 415)]
+ [Produces("application/json")]
+ public IActionResult AllowedTypesThumb(string f)
+ {
+ if ( !ModelState.IsValid )
{
- var mimeTypes = ExtensionRolesHelper.ExtensionThumbSupportedList
- .Select(MimeHelper.GetMimeType).ToHashSet();
- return Json(mimeTypes);
+ return BadRequest("ModelState is not valid");
}
- ///
- /// Check if IsExtensionThumbnailSupported
- ///
- /// Json list
- /// the name with extension and no parent path
- /// is supported
- /// the extenstion from the filename is not supported to generate thumbnails
- /// please login first
- [HttpGet("/api/allowed-types/thumb")]
- [ProducesResponseType(typeof(bool), 200)]
- [ProducesResponseType(typeof(bool), 415)]
- [Produces("application/json")]
- public IActionResult AllowedTypesThumb(string f)
+ var result = ExtensionRolesHelper.IsExtensionThumbnailSupported(f);
+ if ( !result )
{
- var result = ExtensionRolesHelper.IsExtensionThumbnailSupported(f);
- if ( !result ) Response.StatusCode = 415;
- return Json(result);
+ Response.StatusCode = 415;
}
+
+ return Json(result);
}
}
diff --git a/starsky/starsky/Controllers/AppSettingsController.cs b/starsky/starsky/Controllers/AppSettingsController.cs
index ad18e0b25b..d077a49ed2 100644
--- a/starsky/starsky/Controllers/AppSettingsController.cs
+++ b/starsky/starsky/Controllers/AppSettingsController.cs
@@ -8,69 +8,73 @@
using starsky.foundation.accountmanagement.Services;
using starsky.foundation.platform.Models;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class AppSettingsController : Controller
{
- [Authorize]
- public sealed class AppSettingsController : Controller
+ private readonly AppSettings _appSettings;
+ private readonly IUpdateAppSettingsByPath _updateAppSettingsByPath;
+
+ public AppSettingsController(AppSettings appSettings,
+ IUpdateAppSettingsByPath updateAppSettingsByPath)
{
- private readonly AppSettings _appSettings;
- private readonly IUpdateAppSettingsByPath _updateAppSettingsByPath;
+ _appSettings = appSettings;
+ _updateAppSettingsByPath = updateAppSettingsByPath;
+ }
- public AppSettingsController(AppSettings appSettings,
- IUpdateAppSettingsByPath updateAppSettingsByPath)
- {
- _appSettings = appSettings;
- _updateAppSettingsByPath = updateAppSettingsByPath;
- }
+ ///
+ /// Show the runtime settings (dont allow AllowAnonymous)
+ ///
+ /// config data, except connection strings
+ /// returns the runtime settings of Starsky
+ [HttpHead("/api/env")]
+ [HttpGet("/api/env")]
+ [Produces("application/json")]
+ [ProducesResponseType(typeof(AppSettings), 200)]
+ [ProducesResponseType(typeof(AppSettings), 401)]
+ [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse",
+ Justification = "Request in tests")]
+ public IActionResult Env()
+ {
+ var appSettings = _appSettings.CloneToDisplay();
- ///
- /// Show the runtime settings (dont allow AllowAnonymous)
- ///
- /// config data, except connection strings
- /// returns the runtime settings of Starsky
- [HttpHead("/api/env")]
- [HttpGet("/api/env")]
- [Produces("application/json")]
- [ProducesResponseType(typeof(AppSettings), 200)]
- [ProducesResponseType(typeof(AppSettings), 401)]
- [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse",
- Justification = "Request in tests")]
- public IActionResult Env()
+ // For end-to-end testing
+ if ( Request != null! && Request.Headers.Any(p => p.Key == "x-force-html") )
{
- var appSettings = _appSettings.CloneToDisplay();
-
- // For end-to-end testing
- if ( Request != null! && Request.Headers.Any(p => p.Key == "x-force-html") )
- {
- Response.Headers.ContentType = "text/html; charset=utf-8";
- }
-
- return Json(appSettings);
+ Response.Headers.ContentType = "text/html; charset=utf-8";
}
- ///
- /// Show the runtime settings (dont allow AllowAnonymous)
- ///
- /// config data, except connection strings
- /// returns the runtime settings of Starsky
- [HttpPost("/api/env")]
- [Produces("application/json")]
- [ProducesResponseType(typeof(AppSettings), 200)]
- [ProducesResponseType(typeof(AppSettings), 401)]
- [Permission(UserManager.AppPermissions.AppSettingsWrite)]
- public async Task UpdateAppSettings(
- AppSettingsTransferObject appSettingTransferObject)
+ return Json(appSettings);
+ }
+
+ ///
+ /// Show the runtime settings (dont allow AllowAnonymous)
+ ///
+ /// config data, except connection strings
+ /// returns the runtime settings of Starsky
+ [HttpPost("/api/env")]
+ [Produces("application/json")]
+ [ProducesResponseType(typeof(AppSettings), 200)]
+ [ProducesResponseType(typeof(AppSettings), 401)]
+ [Permission(UserManager.AppPermissions.AppSettingsWrite)]
+ public async Task UpdateAppSettings(
+ AppSettingsTransferObject appSettingTransferObject)
+ {
+ if ( !ModelState.IsValid )
{
- var result = await _updateAppSettingsByPath.UpdateAppSettingsAsync(
- appSettingTransferObject);
+ return BadRequest("ModelState is not valid");
+ }
- if ( !result.IsError )
- {
- return Env();
- }
+ var result = await _updateAppSettingsByPath.UpdateAppSettingsAsync(
+ appSettingTransferObject);
- Response.StatusCode = result.StatusCode;
- return Content(result.Message);
+ if ( !result.IsError )
+ {
+ return Env();
}
+
+ Response.StatusCode = result.StatusCode;
+ return Content(result.Message);
}
}
diff --git a/starsky/starsky/Controllers/CacheIndexController.cs b/starsky/starsky/Controllers/CacheIndexController.cs
index 65c0d1d79a..21e3597301 100644
--- a/starsky/starsky/Controllers/CacheIndexController.cs
+++ b/starsky/starsky/Controllers/CacheIndexController.cs
@@ -4,80 +4,100 @@
using starsky.foundation.database.Interfaces;
using starsky.foundation.platform.Models;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class CacheIndexController : Controller
{
- [Authorize]
- public sealed class CacheIndexController : Controller
+ private readonly AppSettings _appSettings;
+ private readonly IQuery _query;
+
+ public CacheIndexController(
+ IQuery query, AppSettings appSettings)
{
- private readonly IQuery _query;
- private readonly AppSettings _appSettings;
+ _appSettings = appSettings;
+ _query = query;
+ }
- public CacheIndexController(
- IQuery query, AppSettings appSettings)
+ ///
+ /// Get Database Cache (only the cache)
+ ///
+ /// subPath (only direct so no dot;comma list)
+ /// redirect or if json enabled a status
+ /// when json"
+ /// "cache disabled in config"
+ ///
+ /// ignored, please check if the 'f' path exist or use a folder string to clear
+ /// the cache
+ ///
+ /// User unauthorized
+ [HttpGet("/api/cache/list")]
+ public IActionResult ListCache(string f = "/")
+ {
+ if ( !ModelState.IsValid )
{
- _appSettings = appSettings;
- _query = query;
+ return BadRequest("ModelState is not valid");
}
- ///
- /// Get Database Cache (only the cache)
- ///
- /// subPath (only direct so no dot;comma list)
- /// redirect or if json enabled a status
- /// when json"
- /// "cache disabled in config"
- /// ignored, please check if the 'f' path exist or use a folder string to clear the cache
- /// User unauthorized
- [HttpGet("/api/cache/list")]
- public IActionResult ListCache(string f = "/")
+ //For folder paths only
+ if ( _appSettings.AddMemoryCache == false )
{
- //For folder paths only
- if ( _appSettings.AddMemoryCache == false )
- {
- Response.StatusCode = 412;
- return Json("cache disabled in config");
- }
-
- var (success, singleItem) = _query.CacheGetParentFolder(f);
- if ( !success || singleItem == null )
- return BadRequest(
- "ignored, please check if the 'f' path exist or use a folder string to get the cache");
+ Response.StatusCode = 412;
+ return Json("cache disabled in config");
+ }
- return Json(singleItem);
+ var (success, singleItem) = _query.CacheGetParentFolder(f);
+ if ( !success || singleItem == null )
+ {
+ return BadRequest(
+ "ignored, please check if the 'f' path exist or use a folder string to get the cache");
}
- ///
- /// Delete Database Cache (only the cache)
- ///
- /// subPath (only direct so no dot;comma list)
- /// redirect or if json enabled a status
- /// when json is true, "cache successful cleared"
- /// "cache disabled in config"
- /// ignored, please check if the 'f' path exist or use a folder string to clear the cache
- /// redirect back to the url
- /// User unauthorized
- [HttpGet("/api/remove-cache")]
- [HttpPost("/api/remove-cache")]
- [ProducesResponseType(200)] // "cache successful cleared"
- [ProducesResponseType(412)] // "cache disabled in config"
- [ProducesResponseType(400)] // "ignored, please check if the 'f' path exist or use a folder string to clear the cache"
- [ProducesResponseType(302)] // redirect back to the url
- public IActionResult RemoveCache(string f = "/")
+ return Json(singleItem);
+ }
+
+ ///
+ /// Delete Database Cache (only the cache)
+ ///
+ /// subPath (only direct so no dot;comma list)
+ /// redirect or if json enabled a status
+ /// when json is true, "cache successful cleared"
+ /// "cache disabled in config"
+ ///
+ /// ignored, please check if the 'f' path exist or use a folder string to clear
+ /// the cache
+ ///
+ /// redirect back to the url
+ /// User unauthorized
+ [HttpGet("/api/remove-cache")]
+ [HttpPost("/api/remove-cache")]
+ [ProducesResponseType(200)] // "cache successful cleared"
+ [ProducesResponseType(412)] // "cache disabled in config"
+ [ProducesResponseType(400)] // "ignored, please check if the 'f' path exist or use a folder string to clear the cache"
+ [ProducesResponseType(302)] // redirect back to the url
+ public IActionResult RemoveCache(string f = "/")
+ {
+ if ( !ModelState.IsValid )
{
- //For folder paths only
- if ( _appSettings.AddMemoryCache == false )
- {
- Response.StatusCode = 412;
- return Json("cache disabled in config");
- }
+ return BadRequest("ModelState is not valid");
+ }
- var singleItem = _query.SingleItem(f);
- if ( singleItem == null || !singleItem.IsDirectory )
- return BadRequest(
- "ignored, please check if the 'f' path exist or use a folder string to clear the cache");
+ //For folder paths only
+ if ( _appSettings.AddMemoryCache == false )
+ {
+ Response.StatusCode = 412;
+ return Json("cache disabled in config");
+ }
- return Json(_query.RemoveCacheParentItem(f) ? "cache successful cleared" : "cache did not exist");
+ var singleItem = _query.SingleItem(f);
+ if ( singleItem == null || !singleItem.IsDirectory )
+ {
+ return BadRequest(
+ "ignored, please check if the 'f' path exist or use a folder string to clear the cache");
}
+ return Json(_query.RemoveCacheParentItem(f)
+ ? "cache successful cleared"
+ : "cache did not exist");
}
}
diff --git a/starsky/starsky/Controllers/DeleteController.cs b/starsky/starsky/Controllers/DeleteController.cs
index 9257b03242..e7b8cf45b9 100644
--- a/starsky/starsky/Controllers/DeleteController.cs
+++ b/starsky/starsky/Controllers/DeleteController.cs
@@ -5,44 +5,52 @@
using starsky.feature.metaupdate.Interfaces;
using starsky.foundation.database.Models;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class DeleteController : Controller
{
- [Authorize]
- public sealed class DeleteController : Controller
+ private readonly IDeleteItem _deleteItem;
+
+ public DeleteController(IDeleteItem deleteItem)
{
- private readonly IDeleteItem _deleteItem;
+ _deleteItem = deleteItem;
+ }
- public DeleteController(IDeleteItem deleteItem)
+ ///
+ /// Remove files from the disk, but the file must contain the !delete!
+ /// (TrashKeyword.TrashKeywordString) tag
+ ///
+ /// subPaths, separated by dot comma
+ /// true is to update files with the same name before the extenstion
+ /// list of deleted files
+ /// file is gone
+ ///
+ /// item not found on disk or !delete! (TrashKeyword.TrashKeywordString) tag is
+ /// missing
+ ///
+ /// User unauthorized
+ [HttpDelete("/api/delete")]
+ [ProducesResponseType(typeof(List), 200)]
+ [ProducesResponseType(typeof(List), 404)]
+ [Produces("application/json")]
+ public async Task Delete(string f, bool collections = false)
+ {
+ if ( !ModelState.IsValid )
{
- _deleteItem = deleteItem;
+ return BadRequest("ModelState is not valid");
}
- ///
- /// Remove files from the disk, but the file must contain the !delete! (TrashKeyword.TrashKeywordString) tag
- ///
- /// subPaths, separated by dot comma
- /// true is to update files with the same name before the extenstion
- /// list of deleted files
- /// file is gone
- /// item not found on disk or !delete! (TrashKeyword.TrashKeywordString) tag is missing
- /// User unauthorized
- [HttpDelete("/api/delete")]
- [ProducesResponseType(typeof(List), 200)]
- [ProducesResponseType(typeof(List), 404)]
- [Produces("application/json")]
- public async Task Delete(string f, bool collections = false)
+ var fileIndexResultsList = await _deleteItem.DeleteAsync(f, collections);
+ // When all items are not found
+ // ok = file is deleted
+ if ( fileIndexResultsList.TrueForAll(p =>
+ p.Status != FileIndexItem.ExifStatus.Ok) )
{
- var fileIndexResultsList = await _deleteItem.DeleteAsync(f, collections);
- // When all items are not found
- // ok = file is deleted
- if ( fileIndexResultsList.TrueForAll(p =>
- p.Status != FileIndexItem.ExifStatus.Ok) )
- {
- return NotFound(fileIndexResultsList);
- }
+ return NotFound(fileIndexResultsList);
+ }
- return Json(fileIndexResultsList);
- }
+ return Json(fileIndexResultsList);
}
}
diff --git a/starsky/starsky/Controllers/DesktopEditorController.cs b/starsky/starsky/Controllers/DesktopEditorController.cs
index 0cfdbbd1ce..9dc2cd584f 100644
--- a/starsky/starsky/Controllers/DesktopEditorController.cs
+++ b/starsky/starsky/Controllers/DesktopEditorController.cs
@@ -18,13 +18,13 @@ public DesktopEditorController(IOpenEditorDesktopService openEditorDesktopServic
}
///
- /// Open a file in the default editor or a specific editor on the desktop
+ /// Open a file in the default editor or a specific editor on the desktop
///
/// single or multiple subPaths
/// to combine files with the same name before the extension
///
/// returns a list of items from the database
- /// list with no content
+ /// list with no content
/// subPath not found in the database
/// User unauthorized
[HttpPost("/api/desktop-editor/open")]
@@ -37,6 +37,11 @@ public async Task OpenAsync(
string f = "",
bool collections = true)
{
+ if ( !ModelState.IsValid )
+ {
+ return BadRequest("ModelState is not valid");
+ }
+
var (success, status, list) =
await _openEditorDesktopService.OpenAsync(f, collections);
@@ -54,7 +59,7 @@ public async Task OpenAsync(
///
- /// Check the amount of files to open before
+ /// Check the amount of files to open before
///
/// single or multiple subPaths
///
@@ -64,8 +69,14 @@ public async Task OpenAsync(
[Produces("application/json")]
[ProducesResponseType(typeof(bool), 200)]
[ProducesResponseType(401)]
+ [ProducesResponseType(400)]
public IActionResult OpenAmountConfirmationChecker(string f)
{
+ if ( !ModelState.IsValid )
+ {
+ return BadRequest("ModelState is not valid");
+ }
+
var result = _openEditorDesktopService.OpenAmountConfirmationChecker(f);
return Json(result);
}
diff --git a/starsky/starsky/Controllers/DiskController.cs b/starsky/starsky/Controllers/DiskController.cs
index e8c8666dc4..7f61dddfea 100644
--- a/starsky/starsky/Controllers/DiskController.cs
+++ b/starsky/starsky/Controllers/DiskController.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -15,146 +16,149 @@
using starsky.foundation.storage.Storage;
using starsky.project.web.ViewModels;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class DiskController : Controller
{
- [Authorize]
- public sealed class DiskController : Controller
+ private readonly IWebSocketConnectionsService _connectionsService;
+ private readonly IStorage _iStorage;
+ private readonly INotificationQuery _notificationQuery;
+ private readonly IQuery _query;
+
+ public DiskController(IQuery query, ISelectorStorage selectorStorage,
+ IWebSocketConnectionsService connectionsService, INotificationQuery notificationQuery)
{
- private readonly IQuery _query;
- private readonly IStorage _iStorage;
- private readonly IWebSocketConnectionsService _connectionsService;
- private readonly INotificationQuery _notificationQuery;
+ _query = query;
+ _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
+ _connectionsService = connectionsService;
+ _notificationQuery = notificationQuery;
+ }
- public DiskController(IQuery query, ISelectorStorage selectorStorage,
- IWebSocketConnectionsService connectionsService, INotificationQuery notificationQuery)
+ ///
+ /// Make a directory (-p)
+ ///
+ /// subPaths split by dot comma
+ /// list of changed files IActionResult Mkdir
+ /// create the item on disk and in db
+ /// A conflict, Directory already exist
+ /// missing path
+ /// User unauthorized
+ [HttpPost("/api/disk/mkdir")]
+ [ProducesResponseType(typeof(List), 200)]
+ [ProducesResponseType(typeof(List), 409)]
+ [ProducesResponseType(typeof(List), 400)]
+ [ProducesResponseType(typeof(string), 401)]
+ [Produces("application/json")]
+ public async Task Mkdir(string f)
+ {
+ var inputFilePaths = PathHelper.SplitInputFilePaths(f).ToList();
+ if ( inputFilePaths.Count == 0 )
{
- _query = query;
- _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
- _connectionsService = connectionsService;
- _notificationQuery = notificationQuery;
+ Response.StatusCode = 400;
+ return Json(new List());
}
- ///
- /// Make a directory (-p)
- ///
- /// subPaths split by dot comma
- /// list of changed files IActionResult Mkdir
- /// create the item on disk and in db
- /// A conflict, Directory already exist
- /// missing path
- /// User unauthorized
- [HttpPost("/api/disk/mkdir")]
- [ProducesResponseType(typeof(List), 200)]
- [ProducesResponseType(typeof(List), 409)]
- [ProducesResponseType(typeof(List), 400)]
- [ProducesResponseType(typeof(string), 401)]
- [Produces("application/json")]
- public async Task Mkdir(string f)
+ var syncResultsList = new List();
+
+ foreach ( var subPath in inputFilePaths.Select(PathHelper.RemoveLatestSlash) )
{
- var inputFilePaths = PathHelper.SplitInputFilePaths(f).ToList();
- if ( inputFilePaths.Count == 0 )
+ var toAddStatus = new SyncViewModel
{
- Response.StatusCode = 400;
- return Json(new List());
- }
+ FilePath = subPath, Status = FileIndexItem.ExifStatus.Ok
+ };
- var syncResultsList = new List();
-
- foreach ( var subPath in inputFilePaths.Select(PathHelper.RemoveLatestSlash) )
+ if ( _iStorage.ExistFolder(subPath) )
{
- var toAddStatus = new SyncViewModel
- {
- FilePath = subPath, Status = FileIndexItem.ExifStatus.Ok
- };
-
- if ( _iStorage.ExistFolder(subPath) )
- {
- toAddStatus.Status = FileIndexItem.ExifStatus.OperationNotSupported;
- syncResultsList.Add(toAddStatus);
- continue;
- }
-
- await _query.AddItemAsync(new FileIndexItem(subPath)
- {
- IsDirectory = true, ImageFormat = ExtensionRolesHelper.ImageFormat.directory
- });
-
- // add to fs
- _iStorage.CreateDirectory(subPath);
-
+ toAddStatus.Status = FileIndexItem.ExifStatus.OperationNotSupported;
syncResultsList.Add(toAddStatus);
+ continue;
}
- // When all items are not found
- if ( syncResultsList.TrueForAll(p => p.Status != FileIndexItem.ExifStatus.Ok) )
- Response.StatusCode = 409; // A conflict, Directory already exist
+ await _query.AddItemAsync(new FileIndexItem(subPath)
+ {
+ IsDirectory = true, ImageFormat = ExtensionRolesHelper.ImageFormat.directory
+ });
- await SyncMessageToSocket(syncResultsList, ApiNotificationType.Mkdir);
+ // add to fs
+ _iStorage.CreateDirectory(subPath);
- return Json(syncResultsList);
+ syncResultsList.Add(toAddStatus);
}
- ///
- /// Update other users with a message from SyncViewModel
- ///
- /// SyncViewModel
- /// optional debug name
- /// Completed send of Socket SendToAllAsync
- private async Task SyncMessageToSocket(IEnumerable syncResultsList,
- ApiNotificationType type = ApiNotificationType.Unknown)
+ // When all items are not found
+ if ( syncResultsList.TrueForAll(p => p.Status != FileIndexItem.ExifStatus.Ok) )
{
- var list = syncResultsList.Select(t => new FileIndexItem(t.FilePath)
- {
- Status = t.Status, IsDirectory = true
- }).ToList();
+ Response.StatusCode = 409; // A conflict, Directory already exist
+ }
- var webSocketResponse = new ApiNotificationResponseModel<
- List>(list, type);
+ await SyncMessageToSocket(syncResultsList, ApiNotificationType.Mkdir);
- await _notificationQuery.AddNotification(webSocketResponse);
- await _connectionsService.SendToAllAsync(webSocketResponse, CancellationToken.None);
- }
+ return Json(syncResultsList);
+ }
- ///
- /// Rename file/folder and update it in the database
- ///
- /// from subPath
- /// to subPath
- /// is collections bool
- /// default is to not included files that are removed in result
- /// list of details form changed files (IActionResult Rename)
- /// the item including the updated content
- /// item not found in the database or on disk
- /// User unauthorized
- [ProducesResponseType(typeof(List), 200)]
- [ProducesResponseType(typeof(List), 404)]
- [HttpPost("/api/disk/rename")]
- [Produces("application/json")]
- public async Task Rename(string f, string to, bool collections = true,
- bool currentStatus = true)
+ ///
+ /// Update other users with a message from SyncViewModel
+ ///
+ /// SyncViewModel
+ /// optional debug name
+ /// Completed send of Socket SendToAllAsync
+ private async Task SyncMessageToSocket(IEnumerable syncResultsList,
+ ApiNotificationType type = ApiNotificationType.Unknown)
+ {
+ var list = syncResultsList.Select(t => new FileIndexItem(t.FilePath)
{
- if ( string.IsNullOrEmpty(f) )
- {
- return BadRequest("No input files");
- }
+ Status = t.Status, IsDirectory = true
+ }).ToList();
- var rename = await new RenameService(_query, _iStorage).Rename(f, to, collections);
+ var webSocketResponse = new ApiNotificationResponseModel<
+ List>(list, type);
- // When all items are not found
- if ( rename.TrueForAll(p => p.Status != FileIndexItem.ExifStatus.Ok) )
- return NotFound(rename);
+ await _notificationQuery.AddNotification(webSocketResponse);
+ await _connectionsService.SendToAllAsync(webSocketResponse, CancellationToken.None);
+ }
- var webSocketResponse =
- new ApiNotificationResponseModel>(rename,
- ApiNotificationType.Rename);
+ ///
+ /// Rename file/folder and update it in the database
+ ///
+ /// from subPath
+ /// to subPath
+ /// is collections bool
+ /// default is to not included files that are removed in result
+ /// list of details form changed files (IActionResult Rename)
+ /// the item including the updated content
+ /// item not found in the database or on disk
+ /// User unauthorized
+ [ProducesResponseType(typeof(List), 200)]
+ [ProducesResponseType(typeof(List), 404)]
+ [HttpPost("/api/disk/rename")]
+ [Produces("application/json")]
+ public async Task Rename([Required] string f, string to, bool collections = true,
+ bool currentStatus = true)
+ {
+ if ( string.IsNullOrEmpty(f) || !ModelState.IsValid )
+ {
+ return BadRequest("No input files");
+ }
- await _notificationQuery.AddNotification(webSocketResponse);
- await _connectionsService.SendToAllAsync(webSocketResponse, CancellationToken.None);
+ var rename = await new RenameService(_query, _iStorage).Rename(f, to, collections);
- return Json(currentStatus
- ? rename.Where(p => p.Status
- != FileIndexItem.ExifStatus.NotFoundSourceMissing).ToList()
- : rename);
+ // When all items are not found
+ if ( rename.TrueForAll(p => p.Status != FileIndexItem.ExifStatus.Ok) )
+ {
+ return NotFound(rename);
}
+
+ var webSocketResponse =
+ new ApiNotificationResponseModel>(rename,
+ ApiNotificationType.Rename);
+
+ await _notificationQuery.AddNotification(webSocketResponse);
+ await _connectionsService.SendToAllAsync(webSocketResponse, CancellationToken.None);
+
+ return Json(currentStatus
+ ? rename.Where(p => p.Status
+ != FileIndexItem.ExifStatus.NotFoundSourceMissing).ToList()
+ : rename);
}
}
diff --git a/starsky/starsky/Controllers/DownloadPhotoController.cs b/starsky/starsky/Controllers/DownloadPhotoController.cs
index 6593541b9f..57bf7b5af9 100644
--- a/starsky/starsky/Controllers/DownloadPhotoController.cs
+++ b/starsky/starsky/Controllers/DownloadPhotoController.cs
@@ -1,3 +1,4 @@
+using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -12,129 +13,147 @@
using starsky.Helpers;
using starsky.project.web.Helpers;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[Authorize]
+public sealed class DownloadPhotoController : Controller
{
- [Authorize]
- public sealed class DownloadPhotoController : Controller
+ private readonly IStorage _iStorage;
+ private readonly IWebLogger _logger;
+ private readonly IQuery _query;
+ private readonly IThumbnailService _thumbnailService;
+ private readonly IStorage _thumbnailStorage;
+
+ public DownloadPhotoController(IQuery query, ISelectorStorage selectorStorage,
+ IWebLogger logger, IThumbnailService thumbnailService)
+ {
+ _query = query;
+ _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
+ _thumbnailStorage = selectorStorage.Get(SelectorStorage.StorageServices.Thumbnail);
+ _thumbnailService = thumbnailService;
+ _logger = logger;
+ }
+
+ ///
+ /// Download sidecar file for example image.xmp
+ ///
+ /// string, subPath to find the file
+ /// FileStream with image
+ /// returns content of the file
+ /// source image missing
+ /// User unauthorized
+ [HttpGet("/api/download-sidecar")]
+ [ProducesResponseType(200)] // file
+ [ProducesResponseType(404)] // not found
+ [ProducesResponseType(400)]
+ public IActionResult DownloadSidecar([Required] string f)
{
- private readonly IQuery _query;
- private readonly IStorage _iStorage;
- private readonly IStorage _thumbnailStorage;
- private readonly IWebLogger _logger;
- private readonly IThumbnailService _thumbnailService;
-
- public DownloadPhotoController(IQuery query, ISelectorStorage selectorStorage,
- IWebLogger logger, IThumbnailService thumbnailService)
+ if ( !ModelState.IsValid )
{
- _query = query;
- _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
- _thumbnailStorage = selectorStorage.Get(SelectorStorage.StorageServices.Thumbnail);
- _thumbnailService = thumbnailService;
- _logger = logger;
+ return BadRequest("ModelState is not valid");
}
- ///
- /// Download sidecar file for example image.xmp
- ///
- /// string, subPath to find the file
- /// FileStream with image
- /// returns content of the file
- /// source image missing
- /// User unauthorized
- [HttpGet("/api/download-sidecar")]
- [ProducesResponseType(200)] // file
- [ProducesResponseType(404)] // not found
- public IActionResult DownloadSidecar(string f)
+ if ( !ExtensionRolesHelper.IsExtensionSidecar(f) )
{
- if ( !ExtensionRolesHelper.IsExtensionSidecar(f) )
- {
- return NotFound("FileName is not a sidecar");
- }
+ return NotFound("FileName is not a sidecar");
+ }
- if ( !_iStorage.ExistFile(f) )
- return NotFound($"source image missing {f}");
+ if ( !_iStorage.ExistFile(f) )
+ {
+ return NotFound($"source image missing {f}");
+ }
- var fs = _iStorage.ReadStream(f);
- return File(fs, MimeHelper.GetMimeTypeByFileName(f));
+ var fs = _iStorage.ReadStream(f);
+ return File(fs, MimeHelper.GetMimeTypeByFileName(f));
+ }
+
+ ///
+ /// Select manually the original or thumbnail
+ ///
+ /// string, 'sub path' to find the file
+ /// true = 1000px thumb (if supported)
+ /// true = send client headers to cache
+ /// FileStream with image
+ /// returns content of the file
+ /// source image missing
+ /// "Thumbnail generation failed"
+ /// User unauthorized
+ [HttpGet("/api/download-photo")]
+ [ProducesResponseType(200)] // file
+ [ProducesResponseType(404)] // not found
+ [ProducesResponseType(500)] // "Thumbnail generation failed"
+ public async Task DownloadPhoto(string f, bool isThumbnail = true,
+ bool cache = true)
+ {
+ if ( !ModelState.IsValid )
+ {
+ return BadRequest("ModelState is not valid");
}
- ///
- /// Select manually the original or thumbnail
- ///
- /// string, 'sub path' to find the file
- /// true = 1000px thumb (if supported)
- /// true = send client headers to cache
- /// FileStream with image
- /// returns content of the file
- /// source image missing
- /// "Thumbnail generation failed"
- /// User unauthorized
- [HttpGet("/api/download-photo")]
- [ProducesResponseType(200)] // file
- [ProducesResponseType(404)] // not found
- [ProducesResponseType(500)] // "Thumbnail generation failed"
- public async Task DownloadPhoto(string f, bool isThumbnail = true,
- bool cache = true)
+ if ( f.Contains("?isthumbnail") )
{
// f = subpath/filepath
- if ( f.Contains("?isthumbnail") )
- {
- return NotFound("please use &isthumbnail = instead of ?isthumbnail= ");
- }
+ return NotFound("please use &isthumbnail = instead of ?isthumbnail= ");
+ }
- var fileIndexItem = await _query.GetObjectByFilePathAsync(f);
- if ( fileIndexItem == null )
+ var fileIndexItem = await _query.GetObjectByFilePathAsync(f);
+ if ( fileIndexItem == null )
+ {
+ return NotFound("not in index " + f);
+ }
+
+ if ( !_iStorage.ExistFile(fileIndexItem.FilePath!) )
+ {
+ return NotFound($"source image missing {fileIndexItem.FilePath}");
+ }
+
+ // Return full image
+ if ( !isThumbnail )
+ {
+ if ( cache )
{
- return NotFound("not in index " + f);
+ CacheControlOverwrite.SetExpiresResponseHeaders(Request);
}
- if ( !_iStorage.ExistFile(fileIndexItem.FilePath!) )
- return NotFound($"source image missing {fileIndexItem.FilePath}");
+ var fileStream = _iStorage.ReadStream(fileIndexItem.FilePath!);
- // Return full image
- if ( !isThumbnail )
- {
- if ( cache ) CacheControlOverwrite.SetExpiresResponseHeaders(Request);
- var fileStream = _iStorage.ReadStream(fileIndexItem.FilePath!);
+ // Return the right mime type (enableRangeProcessing = needed for safari and mp4)
+ return File(fileStream, MimeHelper.GetMimeTypeByFileName(fileIndexItem.FilePath!),
+ true);
+ }
- // Return the right mime type (enableRangeProcessing = needed for safari and mp4)
- return File(fileStream, MimeHelper.GetMimeTypeByFileName(fileIndexItem.FilePath!),
- true);
- }
+ if ( !_thumbnailStorage.ExistFolder("/") )
+ {
+ return NotFound("ThumbnailTempFolder not found");
+ }
- if ( !_thumbnailStorage.ExistFolder("/") )
- {
- return NotFound("ThumbnailTempFolder not found");
- }
+ var data = new ThumbnailSizesExistStatusModel
+ {
+ Small = _thumbnailStorage.ExistFile(
+ ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Small)),
+ Large = _thumbnailStorage.ExistFile(
+ ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Large)),
+ ExtraLarge = _thumbnailStorage.ExistFile(
+ ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.ExtraLarge))
+ };
- var data = new ThumbnailSizesExistStatusModel
- {
- Small = _thumbnailStorage.ExistFile(
- ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Small)),
- Large = _thumbnailStorage.ExistFile(
- ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Large)),
- ExtraLarge = _thumbnailStorage.ExistFile(
- ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.ExtraLarge))
- };
-
- if ( !data.Small || !data.Large || !data.ExtraLarge )
+ if ( !data.Small || !data.Large || !data.ExtraLarge )
+ {
+ _logger.LogDebug("Thumbnail generation started");
+ await _thumbnailService.CreateThumbAsync(fileIndexItem.FilePath!,
+ fileIndexItem.FileHash!);
+
+ if ( !_thumbnailStorage.ExistFile(
+ ThumbnailNameHelper.Combine(fileIndexItem.FileHash!,
+ ThumbnailSize.Large)) )
{
- _logger.LogDebug("Thumbnail generation started");
- await _thumbnailService.CreateThumbAsync(fileIndexItem.FilePath!,
- fileIndexItem.FileHash!);
-
- if ( !_thumbnailStorage.ExistFile(
- ThumbnailNameHelper.Combine(fileIndexItem.FileHash!,
- ThumbnailSize.Large)) )
- {
- Response.StatusCode = 500;
- return Json("Thumbnail generation failed");
- }
+ Response.StatusCode = 500;
+ return Json("Thumbnail generation failed");
}
-
- var thumbnailFileStream = _thumbnailStorage.ReadStream(
- ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Large));
- return File(thumbnailFileStream, "image/jpeg");
}
+
+ var thumbnailFileStream = _thumbnailStorage.ReadStream(
+ ThumbnailNameHelper.Combine(fileIndexItem.FileHash!, ThumbnailSize.Large));
+ return File(thumbnailFileStream, "image/jpeg");
}
}
diff --git a/starsky/starsky/Controllers/ErrorController.cs b/starsky/starsky/Controllers/ErrorController.cs
index 5ad82af93d..57689595a5 100644
--- a/starsky/starsky/Controllers/ErrorController.cs
+++ b/starsky/starsky/Controllers/ErrorController.cs
@@ -3,37 +3,40 @@
using Microsoft.AspNetCore.Mvc;
using starsky.foundation.platform.Models;
-namespace starsky.Controllers
+namespace starsky.Controllers;
+
+[AllowAnonymous]
+public sealed class ErrorController : Controller
{
- [AllowAnonymous]
- public sealed class ErrorController : Controller
+ private readonly string _clientApp;
+
+ public ErrorController(AppSettings appSettings)
{
- private readonly string _clientApp;
+ _clientApp = Path.Combine(appSettings.BaseDirectoryProject,
+ "clientapp", "build", "index.html");
+ }
- public ErrorController(AppSettings appSettings)
+ ///
+ /// Return Error page (HTML)
+ ///
+ /// to add the status code to the response
+ /// Any Error html page
+ [HttpGet("/error")]
+ [Produces("text/html")]
+ public IActionResult Error(int? statusCode = null)
+ {
+ if ( !ModelState.IsValid )
{
- _clientApp = Path.Combine(appSettings.BaseDirectoryProject,
- "clientapp", "build", "index.html");
+ return BadRequest("Model is invalid");
}
- ///
- /// Return Error page (HTML)
- ///
- /// to add the status code to the response
- /// Any Error html page
- [HttpGet("/error")]
- [Produces("text/html")]
- public IActionResult Error(int? statusCode = null)
+ if ( statusCode.HasValue )
{
- if ( statusCode.HasValue )
- {
- // here is the trick
- HttpContext.Response.StatusCode = statusCode.Value;
- }
-
- // or "~/error/${statusCode}.html"
- return PhysicalFile(_clientApp, "text/html");
+ // here is the trick
+ HttpContext.Response.StatusCode = statusCode.Value;
}
- }
+ // or "~/error/${statusCode}.html"
+ return PhysicalFile(_clientApp, "text/html");
+ }
}
diff --git a/starsky/starsky/Controllers/UploadController.cs b/starsky/starsky/Controllers/UploadController.cs
index 61840c98a3..e5ec1643ba 100644
--- a/starsky/starsky/Controllers/UploadController.cs
+++ b/starsky/starsky/Controllers/UploadController.cs
@@ -15,7 +15,6 @@
using starsky.foundation.database.Interfaces;
using starsky.foundation.database.Models;
using starsky.foundation.http.Streaming;
-using starsky.foundation.thumbnailmeta.Interfaces;
using starsky.foundation.platform.Enums;
using starsky.foundation.platform.Helpers;
using starsky.foundation.platform.Interfaces;
@@ -24,301 +23,324 @@
using starsky.foundation.storage.Interfaces;
using starsky.foundation.storage.Storage;
using starsky.foundation.sync.SyncServices;
+using starsky.foundation.thumbnailmeta.Interfaces;
+
+namespace starsky.Controllers;
-namespace starsky.Controllers
+[Authorize] // <- should be logged in!
+[SuppressMessage("Usage", "S5693:Make sure the content " +
+ "length limit is safe here", Justification = "Is checked")]
+public sealed class UploadController : Controller
{
- [Authorize] // <- should be logged in!
- [SuppressMessage("Usage", "S5693:Make sure the content " +
- "length limit is safe here", Justification = "Is checked")]
- public sealed class UploadController : Controller
+ private readonly AppSettings _appSettings;
+ private readonly IStorage _iHostStorage;
+ private readonly IImport _import;
+ private readonly IStorage _iStorage;
+ private readonly IWebLogger _logger;
+ private readonly IMetaExifThumbnailService _metaExifThumbnailService;
+ private readonly IMetaUpdateStatusThumbnailService _metaUpdateStatusThumbnailService;
+ private readonly IQuery _query;
+ private readonly IRealtimeConnectionsService _realtimeService;
+ private readonly ISelectorStorage _selectorStorage;
+
+ [SuppressMessage("Usage",
+ "S107: Constructor has 8 parameters, which is greater than the 7 authorized")]
+ public UploadController(IImport import, AppSettings appSettings,
+ ISelectorStorage selectorStorage, IQuery query,
+ IRealtimeConnectionsService realtimeService, IWebLogger logger,
+ IMetaExifThumbnailService metaExifThumbnailService,
+ IMetaUpdateStatusThumbnailService metaUpdateStatusThumbnailService)
{
- private readonly AppSettings _appSettings;
- private readonly IImport _import;
- private readonly IStorage _iStorage;
- private readonly IStorage _iHostStorage;
- private readonly IQuery _query;
- private readonly ISelectorStorage _selectorStorage;
- private readonly IRealtimeConnectionsService _realtimeService;
- private readonly IWebLogger _logger;
- private readonly IMetaExifThumbnailService _metaExifThumbnailService;
- private readonly IMetaUpdateStatusThumbnailService _metaUpdateStatusThumbnailService;
-
- [SuppressMessage("Usage",
- "S107: Constructor has 8 parameters, which is greater than the 7 authorized")]
- public UploadController(IImport import, AppSettings appSettings,
- ISelectorStorage selectorStorage, IQuery query,
- IRealtimeConnectionsService realtimeService, IWebLogger logger,
- IMetaExifThumbnailService metaExifThumbnailService,
- IMetaUpdateStatusThumbnailService metaUpdateStatusThumbnailService)
+ _appSettings = appSettings;
+ _import = import;
+ _query = query;
+ _selectorStorage = selectorStorage;
+ _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
+ _iHostStorage = selectorStorage.Get(SelectorStorage.StorageServices.HostFilesystem);
+ _realtimeService = realtimeService;
+ _logger = logger;
+ _metaExifThumbnailService = metaExifThumbnailService;
+ _metaUpdateStatusThumbnailService =
+ metaUpdateStatusThumbnailService;
+ }
+
+ ///
+ /// Upload to specific folder (does not check if already has been imported)
+ /// Use the header 'to' to determine the location to where to upload
+ /// Add header 'filename' when uploading direct without form
+ /// (ActionResult UploadToFolder)
+ ///
+ /// done
+ /// folder not found
+ /// Wrong input (e.g. wrong extenstion type)
+ /// missing 'to' header
+ /// the ImportIndexItem of the imported files
+ [HttpPost("/api/upload")]
+ [DisableFormValueModelBinding]
+ [RequestFormLimits(MultipartBodyLengthLimit = 320_000_000)]
+ [RequestSizeLimit(320_000_000)] // in bytes, 305MB
+ [ProducesResponseType(typeof(List), 200)] // yes
+ [ProducesResponseType(typeof(string), 400)]
+ [ProducesResponseType(typeof(List), 404)]
+ [ProducesResponseType(typeof(List),
+ 415)] // Wrong input (e.g. wrong extenstion type)
+ [Produces("application/json")]
+ [SuppressMessage("Usage", "S6932: Use model binding instead of accessing the raw request data")]
+ public async Task UploadToFolder()
+ {
+ var to = Request.Headers["to"].ToString();
+ if ( string.IsNullOrWhiteSpace(to) )
{
- _appSettings = appSettings;
- _import = import;
- _query = query;
- _selectorStorage = selectorStorage;
- _iStorage = selectorStorage.Get(SelectorStorage.StorageServices.SubPath);
- _iHostStorage = selectorStorage.Get(SelectorStorage.StorageServices.HostFilesystem);
- _realtimeService = realtimeService;
- _logger = logger;
- _metaExifThumbnailService = metaExifThumbnailService;
- _metaUpdateStatusThumbnailService =
- metaUpdateStatusThumbnailService;
+ return BadRequest("missing 'to' header");
}
- ///
- /// Upload to specific folder (does not check if already has been imported)
- /// Use the header 'to' to determine the location to where to upload
- /// Add header 'filename' when uploading direct without form
- /// (ActionResult UploadToFolder)
- ///
- /// done
- /// folder not found
- /// Wrong input (e.g. wrong extenstion type)
- /// missing 'to' header
- /// the ImportIndexItem of the imported files
- [HttpPost("/api/upload")]
- [DisableFormValueModelBinding]
- [RequestFormLimits(MultipartBodyLengthLimit = 320_000_000)]
- [RequestSizeLimit(320_000_000)] // in bytes, 305MB
- [ProducesResponseType(typeof(List), 200)] // yes
- [ProducesResponseType(typeof(string), 400)]
- [ProducesResponseType(typeof(List), 404)]
- [ProducesResponseType(typeof(List),
- 415)] // Wrong input (e.g. wrong extenstion type)
- [Produces("application/json")]
- public async Task UploadToFolder()
+ var parentDirectory = GetParentDirectoryFromRequestHeader();
+ if ( parentDirectory == null )
{
- var to = Request.Headers["to"].ToString();
- if ( string.IsNullOrWhiteSpace(to) ) return BadRequest("missing 'to' header");
+ return NotFound(new ImportIndexItem { Status = ImportStatus.ParentDirectoryNotFound });
+ }
+
+ var tempImportPaths = await Request.StreamFile(_appSettings, _selectorStorage);
+
+ var fileIndexResultsList = await _import.Preflight(tempImportPaths,
+ new ImportSettingsModel { IndexMode = false });
+ // fail/pass, right type, string=subPath, string?2= error reason
+ var metaResultsList = new List<(bool, bool, string, string?)>();
- var parentDirectory = GetParentDirectoryFromRequestHeader();
- if ( parentDirectory == null )
+ for ( var i = 0; i < fileIndexResultsList.Count; i++ )
+ {
+ if ( fileIndexResultsList[i].Status != ImportStatus.Ok )
{
- return NotFound(new ImportIndexItem
- {
- Status = ImportStatus.ParentDirectoryNotFound
- });
+ continue;
}
- var tempImportPaths = await Request.StreamFile(_appSettings, _selectorStorage);
+ var tempFileStream = _iHostStorage.ReadStream(tempImportPaths[i]);
- var fileIndexResultsList = await _import.Preflight(tempImportPaths,
- new ImportSettingsModel { IndexMode = false });
- // fail/pass, right type, string=subPath, string?2= error reason
- var metaResultsList = new List<(bool, bool, string, string?)>();
+ var fileName = Path.GetFileName(tempImportPaths[i]);
- for ( var i = 0; i < fileIndexResultsList.Count; i++ )
+ // subPath is always unix style
+ var subPath = PathHelper.AddSlash(parentDirectory) + fileName;
+ if ( parentDirectory == "/" )
{
- if ( fileIndexResultsList[i].Status != ImportStatus.Ok )
- {
- continue;
- }
-
- var tempFileStream = _iHostStorage.ReadStream(tempImportPaths[i]);
-
- var fileName = Path.GetFileName(tempImportPaths[i]);
-
- // subPath is always unix style
- var subPath = PathHelper.AddSlash(parentDirectory) + fileName;
- if ( parentDirectory == "/" ) subPath = parentDirectory + fileName;
-
- // to get the output in the result right
- fileIndexResultsList[i].FileIndexItem!.FileName = fileName;
- fileIndexResultsList[i].FileIndexItem!.ParentDirectory = parentDirectory;
- fileIndexResultsList[i].FilePath = subPath;
- // Do sync action before writing it down
- fileIndexResultsList[i].FileIndexItem =
- await SyncItem(fileIndexResultsList[i].FileIndexItem!);
-
- var writeStatus =
- await _iStorage.WriteStreamAsync(tempFileStream, subPath + ".tmp");
- // Is already flushed / disposed when the stream is written
-
- // to avoid partly written stream to be read by an other application
- _iStorage.FileDelete(subPath);
- _iStorage.FileMove(subPath + ".tmp", subPath);
- _logger.LogInformation($"[UploadController] write {subPath} is {writeStatus}");
-
- // clear directory cache
- _query.RemoveCacheParentItem(subPath);
-
- var deleteStatus = _iHostStorage.FileDelete(tempImportPaths[i]);
- _logger.LogInformation(
- $"[UploadController] delete {tempImportPaths[i]} is {deleteStatus}");
-
- var parentPath = Directory.GetParent(tempImportPaths[i])?.FullName;
- if ( !string.IsNullOrEmpty(parentPath) && parentPath != _appSettings.TempFolder )
- {
- _iHostStorage.FolderDelete(parentPath);
- }
-
- metaResultsList.Add(( await _metaExifThumbnailService.AddMetaThumbnail(subPath,
- fileIndexResultsList[i].FileIndexItem!.FileHash!) ));
+ subPath = parentDirectory + fileName;
}
- // send all uploads as list
- var socketResult = fileIndexResultsList
- .Where(p => p.Status == ImportStatus.Ok)
- .Select(item => item.FileIndexItem).Cast().ToList();
+ // to get the output in the result right
+ fileIndexResultsList[i].FileIndexItem!.FileName = fileName;
+ fileIndexResultsList[i].FileIndexItem!.ParentDirectory = parentDirectory;
+ fileIndexResultsList[i].FilePath = subPath;
+ // Do sync action before writing it down
+ fileIndexResultsList[i].FileIndexItem =
+ await SyncItem(fileIndexResultsList[i].FileIndexItem!);
+
+ var writeStatus =
+ await _iStorage.WriteStreamAsync(tempFileStream, subPath + ".tmp");
+ // Is already flushed / disposed when the stream is written
- var webSocketResponse = new ApiNotificationResponseModel>(
- socketResult, ApiNotificationType.UploadFile);
- await _realtimeService.NotificationToAllAsync(webSocketResponse,
- CancellationToken.None);
+ // to avoid partly written stream to be read by an other application
+ _iStorage.FileDelete(subPath);
+ _iStorage.FileMove(subPath + ".tmp", subPath);
+ _logger.LogInformation($"[UploadController] write {subPath} is {writeStatus}");
- await _metaUpdateStatusThumbnailService.UpdateStatusThumbnail(metaResultsList);
+ // clear directory cache
+ _query.RemoveCacheParentItem(subPath);
- // Wrong input (extension is not allowed)
- if ( fileIndexResultsList.TrueForAll(p => p.Status == ImportStatus.FileError) )
+ var deleteStatus = _iHostStorage.FileDelete(tempImportPaths[i]);
+ _logger.LogInformation(
+ $"[UploadController] delete {tempImportPaths[i]} is {deleteStatus}");
+
+ var parentPath = Directory.GetParent(tempImportPaths[i])?.FullName;
+ if ( !string.IsNullOrEmpty(parentPath) && parentPath != _appSettings.TempFolder )
{
- _logger.LogInformation($"Wrong input extension is not allowed" +
- $" {string.Join(",", fileIndexResultsList.Select(p => p.FilePath))}");
- Response.StatusCode = 415;
+ _iHostStorage.FolderDelete(parentPath);
}
- return Json(fileIndexResultsList);
+ metaResultsList.Add(await _metaExifThumbnailService.AddMetaThumbnail(subPath,
+ fileIndexResultsList[i].FileIndexItem!.FileHash!));
}
- ///
- /// Perform database updates
- ///
- /// to update to
- /// updated item
- private async Task SyncItem(FileIndexItem metaDataItem)
+ // send all uploads as list
+ var socketResult = fileIndexResultsList
+ .Where(p => p.Status == ImportStatus.Ok)
+ .Select(item => item.FileIndexItem).Cast().ToList();
+
+ var webSocketResponse = new ApiNotificationResponseModel>(
+ socketResult, ApiNotificationType.UploadFile);
+ await _realtimeService.NotificationToAllAsync(webSocketResponse,
+ CancellationToken.None);
+
+ await _metaUpdateStatusThumbnailService.UpdateStatusThumbnail(metaResultsList);
+
+ // Wrong input (extension is not allowed)
+ if ( fileIndexResultsList.TrueForAll(p => p.Status == ImportStatus.FileError) )
{
- var itemFromDatabase = await _query.GetObjectByFilePathAsync(metaDataItem.FilePath!);
- if ( itemFromDatabase == null )
- {
- AddOrRemoveXmpSidecarFileToDatabase(metaDataItem);
- await _query.AddItemAsync(metaDataItem);
- return metaDataItem;
- }
+ _logger.LogInformation($"Wrong input extension is not allowed" +
+ $" {string.Join(",", fileIndexResultsList.Select(p => p.FilePath))}");
+ Response.StatusCode = 415;
+ }
- FileIndexCompareHelper.Compare(itemFromDatabase, metaDataItem);
- AddOrRemoveXmpSidecarFileToDatabase(metaDataItem);
+ return Json(fileIndexResultsList);
+ }
- await _query.UpdateItemAsync(itemFromDatabase);
- return itemFromDatabase;
+ ///
+ /// Perform database updates
+ ///
+ /// to update to
+ /// updated item
+ private async Task SyncItem(FileIndexItem metaDataItem)
+ {
+ var itemFromDatabase = await _query.GetObjectByFilePathAsync(metaDataItem.FilePath!);
+ if ( itemFromDatabase == null )
+ {
+ AddOrRemoveXmpSidecarFileToDatabase(metaDataItem);
+ await _query.AddItemAsync(metaDataItem);
+ return metaDataItem;
}
- private void AddOrRemoveXmpSidecarFileToDatabase(FileIndexItem metaDataItem)
+ FileIndexCompareHelper.Compare(itemFromDatabase, metaDataItem);
+ AddOrRemoveXmpSidecarFileToDatabase(metaDataItem);
+
+ await _query.UpdateItemAsync(itemFromDatabase);
+ return itemFromDatabase;
+ }
+
+ private void AddOrRemoveXmpSidecarFileToDatabase(FileIndexItem metaDataItem)
+ {
+ if ( _iStorage.ExistFile(ExtensionRolesHelper.ReplaceExtensionWithXmp(metaDataItem
+ .FilePath)) )
{
- if ( _iStorage.ExistFile(ExtensionRolesHelper.ReplaceExtensionWithXmp(metaDataItem
- .FilePath)) )
- {
- metaDataItem.AddSidecarExtension("xmp");
- return;
- }
+ metaDataItem.AddSidecarExtension("xmp");
+ return;
+ }
+
+ metaDataItem.RemoveSidecarExtension("xmp");
+ }
- metaDataItem.RemoveSidecarExtension("xmp");
+ ///
+ /// Check if xml can be parsed
+ /// Used by sidecar upload
+ ///
+ /// string with xml
+ /// true when parsed
+ private bool IsValidXml(string xml)
+ {
+ try
+ {
+ // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
+ XDocument.Parse(xml);
+ return true;
+ }
+ catch
+ {
+ _logger.LogInformation("[IsValidXml] non valid xml");
+ return false;
}
+ }
- ///
- /// Check if xml can be parsed
- /// Used by sidecar upload
- ///
- /// string with xml
- /// true when parsed
- private bool IsValidXml(string xml)
+ ///
+ /// Upload sidecar file to specific folder (does not check if already has been imported)
+ /// Use the header 'to' to determine the location to where to upload
+ /// Add header 'filename' when uploading direct without form
+ /// (ActionResult UploadToFolderSidecarFile)
+ ///
+ /// done
+ /// parent folder not found
+ /// Wrong input (e.g. wrong extenstion type)
+ /// missing 'to' header
+ /// the ImportIndexItem of the imported files
+ [HttpPost("/api/upload-sidecar")]
+ [DisableFormValueModelBinding]
+ [RequestFormLimits(MultipartBodyLengthLimit = 3_000_000)]
+ [RequestSizeLimit(3_000_000)] // in bytes, 3 MB
+ [ProducesResponseType(typeof(List), 200)] // yes
+ [ProducesResponseType(typeof(string), 400)]
+ [ProducesResponseType(typeof(List), 404)] // parent dir not found
+ [ProducesResponseType(typeof(List),
+ 415)] // Wrong input (e.g. wrong extenstion type)
+ [Produces("application/json")]
+ [SuppressMessage("Usage", "S6932: Use model binding instead of accessing the raw request data")]
+ public async Task UploadToFolderSidecarFile()
+ {
+ var to = Request.Headers["to"].ToString();
+ if ( string.IsNullOrWhiteSpace(to) )
{
- try
- {
- // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
- XDocument.Parse(xml);
- return true;
- }
- catch
- {
- _logger.LogInformation("[IsValidXml] non valid xml");
- return false;
- }
+ return BadRequest("missing 'to' header");
}
- ///
- /// Upload sidecar file to specific folder (does not check if already has been imported)
- /// Use the header 'to' to determine the location to where to upload
- /// Add header 'filename' when uploading direct without form
- /// (ActionResult UploadToFolderSidecarFile)
- ///
- /// done
- /// parent folder not found
- /// Wrong input (e.g. wrong extenstion type)
- /// missing 'to' header
- /// the ImportIndexItem of the imported files
- [HttpPost("/api/upload-sidecar")]
- [DisableFormValueModelBinding]
- [RequestFormLimits(MultipartBodyLengthLimit = 3_000_000)]
- [RequestSizeLimit(3_000_000)] // in bytes, 3 MB
- [ProducesResponseType(typeof(List), 200)] // yes
- [ProducesResponseType(typeof(string), 400)]
- [ProducesResponseType(typeof(List), 404)] // parent dir not found
- [ProducesResponseType(typeof(List),
- 415)] // Wrong input (e.g. wrong extenstion type)
- [Produces("application/json")]
- public async Task UploadToFolderSidecarFile()
+ _logger.LogInformation($"[UploadToFolderSidecarFile] to:{to}");
+
+ var parentDirectory = GetParentDirectoryFromRequestHeader();
+ if ( parentDirectory == null )
{
- var to = Request.Headers["to"].ToString();
- if ( string.IsNullOrWhiteSpace(to) ) return BadRequest("missing 'to' header");
- _logger.LogInformation($"[UploadToFolderSidecarFile] to:{to}");
+ return NotFound(new ImportIndexItem());
+ }
+
+ var tempImportPaths = await Request.StreamFile(_appSettings, _selectorStorage);
- var parentDirectory = GetParentDirectoryFromRequestHeader();
- if ( parentDirectory == null )
+ var importedList = new List();
+ foreach ( var tempImportSinglePath in tempImportPaths )
+ {
+ var data = await StreamToStringHelper.StreamToStringAsync(
+ _iHostStorage.ReadStream(tempImportSinglePath));
+ if ( !IsValidXml(data) )
{
- return NotFound(new ImportIndexItem());
+ continue;
}
- var tempImportPaths = await Request.StreamFile(_appSettings, _selectorStorage);
+ var tempFileStream = _iHostStorage.ReadStream(tempImportSinglePath);
+ var fileName = Path.GetFileName(tempImportSinglePath);
- var importedList = new List();
- foreach ( var tempImportSinglePath in tempImportPaths )
+ var subPath = PathHelper.AddSlash(parentDirectory) + fileName;
+ if ( parentDirectory == "/" )
{
- var data = await StreamToStringHelper.StreamToStringAsync(
- _iHostStorage.ReadStream(tempImportSinglePath));
- if ( !IsValidXml(data) ) continue;
-
- var tempFileStream = _iHostStorage.ReadStream(tempImportSinglePath);
- var fileName = Path.GetFileName(tempImportSinglePath);
-
- var subPath = PathHelper.AddSlash(parentDirectory) + fileName;
- if ( parentDirectory == "/" ) subPath = parentDirectory + fileName;
-
- if ( _appSettings.UseDiskWatcher == false )
- {
- await new SyncSingleFile(_appSettings, _query,
- _iStorage, null!, _logger).UpdateSidecarFile(subPath);
- }
-
- await _iStorage.WriteStreamAsync(tempFileStream, subPath);
- await tempFileStream.DisposeAsync();
- importedList.Add(subPath);
-
- var deleteStatus = _iHostStorage.FileDelete(tempImportSinglePath);
- _logger.LogInformation($"delete {tempImportSinglePath} is {deleteStatus}");
+ subPath = parentDirectory + fileName;
}
- if ( importedList.Count == 0 )
+ if ( _appSettings.UseDiskWatcher == false )
{
- Response.StatusCode = 415;
+ await new SyncSingleFile(_appSettings, _query,
+ _iStorage, null!, _logger).UpdateSidecarFile(subPath);
}
- return Json(importedList);
+ await _iStorage.WriteStreamAsync(tempFileStream, subPath);
+ await tempFileStream.DisposeAsync();
+ importedList.Add(subPath);
+
+ var deleteStatus = _iHostStorage.FileDelete(tempImportSinglePath);
+ _logger.LogInformation($"delete {tempImportSinglePath} is {deleteStatus}");
}
- internal string? GetParentDirectoryFromRequestHeader()
+ if ( importedList.Count == 0 )
{
- var to = Request.Headers["to"].ToString();
- if ( to == "/" ) return "/";
+ Response.StatusCode = 415;
+ }
- // only used for direct import
- if ( _iStorage.ExistFolder(FilenamesHelper.GetParentPath(to)) &&
- FilenamesHelper.IsValidFileName(FilenamesHelper.GetFileName(to)) )
- {
- Request.Headers["filename"] = FilenamesHelper.GetFileName(to);
- return FilenamesHelper.GetParentPath(PathHelper.RemoveLatestSlash(to));
- }
+ return Json(importedList);
+ }
+
+ [SuppressMessage("Usage", "S6932: Use model binding instead of accessing the raw request data")]
+ internal string? GetParentDirectoryFromRequestHeader()
+ {
+ var to = Request.Headers["to"].ToString();
+ if ( to == "/" )
+ {
+ return "/";
+ }
+
+ // only used for direct import
+ if ( _iStorage.ExistFolder(FilenamesHelper.GetParentPath(to)) &&
+ FilenamesHelper.IsValidFileName(FilenamesHelper.GetFileName(to)) )
+ {
+ Request.Headers["filename"] = FilenamesHelper.GetFileName(to);
+ return FilenamesHelper.GetParentPath(PathHelper.RemoveLatestSlash(to));
+ }
- // ReSharper disable once ConvertIfStatementToReturnStatement
- if ( !_iStorage.ExistFolder(PathHelper.RemoveLatestSlash(to)) ) return null;
- return PathHelper.RemoveLatestSlash(to);
+ // ReSharper disable once ConvertIfStatementToReturnStatement
+ if ( !_iStorage.ExistFolder(PathHelper.RemoveLatestSlash(to)) )
+ {
+ return null;
}
+
+ return PathHelper.RemoveLatestSlash(to);
}
}
diff --git a/starsky/starskytest/Controllers/AllowedTypesControllerTest.cs b/starsky/starskytest/Controllers/AllowedTypesControllerTest.cs
index 20540ca6a1..5fd86c048e 100644
--- a/starsky/starskytest/Controllers/AllowedTypesControllerTest.cs
+++ b/starsky/starskytest/Controllers/AllowedTypesControllerTest.cs
@@ -4,43 +4,62 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using starsky.Controllers;
-namespace starskytest.Controllers
+namespace starskytest.Controllers;
+
+[TestClass]
+public sealed class AllowedTypesControllerTest
{
- [TestClass]
- public sealed class AllowedTypesControllerTest
+ private readonly HttpContext _httpContext = new DefaultHttpContext();
+
+ [TestMethod]
+ public void AllowedTypesController_MimetypeSync()
+ {
+ var jsonResult = new AllowedTypesController().AllowedTypesMimetypeSync() as JsonResult;
+ var allowedApiResult = jsonResult?.Value as HashSet;
+ Assert.IsTrue(allowedApiResult?.Contains("image/jpeg"));
+ }
+
+ [TestMethod]
+ public void AllowedTypesController_MimetypeSyncThumb()
{
- private readonly HttpContext _httpContext = new DefaultHttpContext();
-
- [TestMethod]
- public void AllowedTypesController_MimetypeSync()
- {
- var jsonResult = new AllowedTypesController().AllowedTypesMimetypeSync() as JsonResult;
- var allowedApiResult = jsonResult?.Value as HashSet;
- Assert.IsTrue(allowedApiResult?.Contains("image/jpeg"));
- }
-
- [TestMethod]
- public void AllowedTypesController_MimetypeSyncThumb()
- {
- var jsonResult = new AllowedTypesController().AllowedTypesMimetypeSyncThumb() as JsonResult;
- var allowedApiResult = jsonResult?.Value as HashSet;
- Assert.IsTrue(allowedApiResult?.Contains("image/jpeg"));
- }
-
- [TestMethod]
- public void AllowedTypesController_AllowedTypesThumb_NoInput()
- {
- var jsonResult = new AllowedTypesController{ ControllerContext = {HttpContext = _httpContext}}.AllowedTypesThumb("") as JsonResult;
- var allowedApiResult = bool.Parse(jsonResult?.Value?.ToString()!);
- Assert.IsFalse(allowedApiResult);
- }
-
- [TestMethod]
- public void AllowedTypesController_AllowedTypesThumb_Example()
- {
- var jsonResult = new AllowedTypesController{ ControllerContext = {HttpContext = _httpContext}}.AllowedTypesThumb("test.jpg") as JsonResult;
- var allowedApiResult = bool.Parse(jsonResult?.Value?.ToString()!);
- Assert.IsTrue(allowedApiResult);
- }
+ var jsonResult = new AllowedTypesController().AllowedTypesMimetypeSyncThumb() as JsonResult;
+ var allowedApiResult = jsonResult?.Value as HashSet;
+ Assert.IsTrue(allowedApiResult?.Contains("image/jpeg"));
+ }
+
+ [TestMethod]
+ public void AllowedTypesController_AllowedTypesThumb_NoInput()
+ {
+ var jsonResult =
+ new AllowedTypesController { ControllerContext = { HttpContext = _httpContext } }
+ .AllowedTypesThumb("") as JsonResult;
+ var allowedApiResult = bool.Parse(jsonResult?.Value?.ToString()!);
+ Assert.IsFalse(allowedApiResult);
+ }
+
+ [TestMethod]
+ public void AllowedTypesController_AllowedTypesThumb_Example()
+ {
+ var jsonResult =
+ new AllowedTypesController { ControllerContext = { HttpContext = _httpContext } }
+ .AllowedTypesThumb("test.jpg") as JsonResult;
+ var allowedApiResult = bool.Parse(jsonResult?.Value?.ToString()!);
+ Assert.IsTrue(allowedApiResult);
+ }
+
+ [TestMethod]
+ public void AllowedTypesController_AllowedTypesThumb_ReturnsBadRequest()
+ {
+ // Arrange
+ var controller =
+ new AllowedTypesController { ControllerContext = { HttpContext = _httpContext } };
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = controller.AllowedTypesThumb("test.jpg");
+
+ // Assert
+ Assert.IsInstanceOfType(result);
}
}
diff --git a/starsky/starskytest/Controllers/AppSettingsControllerTest.cs b/starsky/starskytest/Controllers/AppSettingsControllerTest.cs
index d16a7bc7a4..7f6b488097 100644
--- a/starsky/starskytest/Controllers/AppSettingsControllerTest.cs
+++ b/starsky/starskytest/Controllers/AppSettingsControllerTest.cs
@@ -13,173 +13,189 @@
using starsky.foundation.storage.Helpers;
using starskytest.FakeMocks;
-namespace starskytest.Controllers
+namespace starskytest.Controllers;
+
+[TestClass]
+public sealed class AppSettingsControllerTest
{
- [TestClass]
- public sealed class AppSettingsControllerTest
+ [TestMethod]
+ public void ENV_StarskyTestEnv()
{
- [TestMethod]
- public void ENV_StarskyTestEnv()
- {
- var controller =
- new AppSettingsController(new AppSettings(), new FakeIUpdateAppSettingsByPath());
- var actionResult = controller.Env() as JsonResult;
- var resultAppSettings = actionResult?.Value as AppSettings;
- Assert.AreEqual("Starsky", resultAppSettings?.Name);
- }
-
- [TestMethod]
- public void ENV_StarskyTestEnv_ForceHtml()
- {
- var controller = new AppSettingsController(new AppSettings(),
- new FakeIUpdateAppSettingsByPath());
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
- controller.ControllerContext.HttpContext.Request.Headers.Append("x-force-html", "true");
- var actionResult = controller.Env() as JsonResult;
- var resultAppSettings = actionResult?.Value as AppSettings;
- Assert.AreEqual("Starsky", resultAppSettings?.Name);
- Assert.AreEqual("text/html; charset=utf-8",
- controller.ControllerContext.HttpContext.Response.Headers.ContentType.ToString());
- }
-
- [TestMethod]
- public async Task UpdateAppSettings_Verbose()
- {
- var appSettings = new AppSettings();
- var storage = new FakeIStorage(new List { "/" });
- var controller = new AppSettingsController(appSettings,
- new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
-
- var actionResult =
- await controller.UpdateAppSettings(new AppSettingsTransferObject { Verbose = true })
- as JsonResult;
- var result = actionResult?.Value as AppSettings;
- Assert.IsTrue(result?.Verbose);
- }
-
- [TestMethod]
- public async Task UpdateAppSettings_StorageFolder()
- {
- var appSettings = new AppSettings();
- var controller = new AppSettingsController(appSettings, new UpdateAppSettingsByPath(
- appSettings,
- new FakeSelectorStorage(
- new FakeIStorage(new List { $"{Path.DirectorySeparatorChar}test" }))));
-
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
-
- var actionResult = await controller.UpdateAppSettings(new AppSettingsTransferObject
- {
- Verbose = true, StorageFolder = $"{Path.DirectorySeparatorChar}test"
- }) as JsonResult;
-
- var result = actionResult?.Value as AppSettings;
- Assert.IsTrue(result?.Verbose);
- Assert.AreEqual(Path.DirectorySeparatorChar + PathHelper.AddBackslash("test"),
- result?.StorageFolder);
- }
-
- [TestMethod]
- public async Task UpdateAppSettingsTest_IgnoreWhenEnvIsSet()
+ var controller =
+ new AppSettingsController(new AppSettings(), new FakeIUpdateAppSettingsByPath());
+ var actionResult = controller.Env() as JsonResult;
+ var resultAppSettings = actionResult?.Value as AppSettings;
+ Assert.AreEqual("Starsky", resultAppSettings?.Name);
+ }
+
+ [TestMethod]
+ public void ENV_StarskyTestEnv_ForceHtml()
+ {
+ var controller = new AppSettingsController(new AppSettings(),
+ new FakeIUpdateAppSettingsByPath());
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ controller.ControllerContext.HttpContext.Request.Headers.Append("x-force-html", "true");
+ var actionResult = controller.Env() as JsonResult;
+ var resultAppSettings = actionResult?.Value as AppSettings;
+ Assert.AreEqual("Starsky", resultAppSettings?.Name);
+ Assert.AreEqual("text/html; charset=utf-8",
+ controller.ControllerContext.HttpContext.Response.Headers.ContentType.ToString());
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettings_Verbose()
+ {
+ var appSettings = new AppSettings();
+ var storage = new FakeIStorage(new List { "/" });
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
+
+ var actionResult =
+ await controller.UpdateAppSettings(new AppSettingsTransferObject { Verbose = true })
+ as JsonResult;
+ var result = actionResult?.Value as AppSettings;
+ Assert.IsTrue(result?.Verbose);
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettings_StorageFolder()
+ {
+ var appSettings = new AppSettings();
+ var controller = new AppSettingsController(appSettings, new UpdateAppSettingsByPath(
+ appSettings,
+ new FakeSelectorStorage(
+ new FakeIStorage(new List { $"{Path.DirectorySeparatorChar}test" }))));
+
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+
+ var actionResult = await controller.UpdateAppSettings(new AppSettingsTransferObject
{
- Environment.SetEnvironmentVariable("app__storageFolder",
- "any_value");
-
- var appSettings = new AppSettings();
- var controller = new AppSettingsController(appSettings,
- new FakeIUpdateAppSettingsByPath(
- new UpdateAppSettingsStatusModel { StatusCode = 403 }));
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
- await controller.UpdateAppSettings(
- new AppSettingsTransferObject { StorageFolder = "test" });
+ Verbose = true, StorageFolder = $"{Path.DirectorySeparatorChar}test"
+ }) as JsonResult;
+
+ var result = actionResult?.Value as AppSettings;
+ Assert.IsTrue(result?.Verbose);
+ Assert.AreEqual(Path.DirectorySeparatorChar + PathHelper.AddBackslash("test"),
+ result?.StorageFolder);
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettingsTest_IgnoreWhenEnvIsSet()
+ {
+ Environment.SetEnvironmentVariable("app__storageFolder",
+ "any_value");
+
+ var appSettings = new AppSettings();
+ var controller = new AppSettingsController(appSettings,
+ new FakeIUpdateAppSettingsByPath(
+ new UpdateAppSettingsStatusModel { StatusCode = 403 }));
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ await controller.UpdateAppSettings(
+ new AppSettingsTransferObject { StorageFolder = "test" });
+
+ Assert.AreEqual(403, controller.Response.StatusCode);
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettingsTest_DirNotFound()
+ {
+ var appSettings = new AppSettings();
+ var controller = new AppSettingsController(appSettings,
+ new FakeIUpdateAppSettingsByPath(
+ new UpdateAppSettingsStatusModel { StatusCode = 404 }));
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- Assert.AreEqual(403, controller.Response.StatusCode);
- }
+ await controller.UpdateAppSettings(
+ new AppSettingsTransferObject { StorageFolder = "not_found" });
- [TestMethod]
- public async Task UpdateAppSettingsTest_DirNotFound()
+ Assert.AreEqual(404, controller.Response.StatusCode);
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettingsTest_StorageFolder_JsonCheck()
+ {
+ var storage = new FakeIStorage(new List { "test" });
+ Environment.SetEnvironmentVariable("app__storageFolder", string.Empty);
+
+ var appSettings = new AppSettings
{
- var appSettings = new AppSettings();
- var controller = new AppSettingsController(appSettings,
- new FakeIUpdateAppSettingsByPath(
- new UpdateAppSettingsStatusModel { StatusCode = 404 }));
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ AppSettingsPath =
+ $"{Path.DirectorySeparatorChar}temp{Path.DirectorySeparatorChar}appsettings.json"
+ };
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
+ await controller.UpdateAppSettings(
+ new AppSettingsTransferObject { Verbose = true, StorageFolder = "test" });
+
+ Assert.IsTrue(storage.ExistFile(appSettings.AppSettingsPath));
+
+ var jsonContent = await StreamToStringHelper.StreamToStringAsync(
+ storage.ReadStream(appSettings.AppSettingsPath));
+ Assert.IsTrue(jsonContent.Contains("app\": {"));
+ Assert.IsTrue(jsonContent.Contains("\"StorageFolder\": \""));
+ }
+
+ [TestMethod]
+ public async Task UpdateAppSettings_UseLocalDesktop()
+ {
+ var appSettings = new AppSettings();
+ var storage = new FakeIStorage(new List { "/" });
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
+
+ var actionResult =
await controller.UpdateAppSettings(
- new AppSettingsTransferObject { StorageFolder = "not_found" });
+ new AppSettingsTransferObject { UseLocalDesktop = true }) as JsonResult;
+ var result = actionResult?.Value as AppSettings;
+ Assert.IsTrue(result?.UseLocalDesktop);
+ }
- Assert.AreEqual(404, controller.Response.StatusCode);
- }
+ [TestMethod]
+ public async Task UpdateAppSettings_UseSystemTrash()
+ {
+ var appSettings = new AppSettings();
+ var storage = new FakeIStorage(new List { "/" });
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
- [TestMethod]
- public async Task UpdateAppSettingsTest_StorageFolder_JsonCheck()
- {
- var storage = new FakeIStorage(new List { "test" });
- Environment.SetEnvironmentVariable("app__storageFolder", string.Empty);
-
- var appSettings = new AppSettings
- {
- AppSettingsPath =
- $"{Path.DirectorySeparatorChar}temp{Path.DirectorySeparatorChar}appsettings.json"
- };
- var controller = new AppSettingsController(appSettings,
- new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
+ var actionResult =
await controller.UpdateAppSettings(
- new AppSettingsTransferObject { Verbose = true, StorageFolder = "test" });
+ new AppSettingsTransferObject { UseSystemTrash = true }) as JsonResult;
+ var result = actionResult?.Value as AppSettings;
+ Assert.IsTrue(result?.UseSystemTrash);
+ }
- Assert.IsTrue(storage.ExistFile(appSettings.AppSettingsPath));
+ [TestMethod]
+ public async Task UpdateAppSettings_Verbose_IgnoreSystemTrashValue()
+ {
+ var appSettings = new AppSettings();
+ var storage = new FakeIStorage(new List { "/" });
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
- var jsonContent = await StreamToStringHelper.StreamToStringAsync(
- storage.ReadStream(appSettings.AppSettingsPath));
+ var actionResult =
+ await controller.UpdateAppSettings(new AppSettingsTransferObject { Verbose = true })
+ as JsonResult;
+ var result = actionResult?.Value as AppSettings;
- Assert.IsTrue(jsonContent.Contains("app\": {"));
- Assert.IsTrue(jsonContent.Contains("\"StorageFolder\": \""));
- }
+ Assert.AreEqual(appSettings.UseSystemTrash, result?.UseSystemTrash);
+ }
- [TestMethod]
- public async Task UpdateAppSettings_UseLocalDesktop()
- {
- var appSettings = new AppSettings();
- var storage = new FakeIStorage(new List { "/" });
- var controller = new AppSettingsController(appSettings,
- new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
-
- var actionResult =
- await controller.UpdateAppSettings(
- new AppSettingsTransferObject { UseLocalDesktop = true }) as JsonResult;
- var result = actionResult?.Value as AppSettings;
- Assert.IsTrue(result?.UseLocalDesktop);
- }
-
- [TestMethod]
- public async Task UpdateAppSettings_UseSystemTrash()
- {
- var appSettings = new AppSettings();
- var storage = new FakeIStorage(new List { "/" });
- var controller = new AppSettingsController(appSettings,
- new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
-
- var actionResult =
- await controller.UpdateAppSettings(
- new AppSettingsTransferObject { UseSystemTrash = true }) as JsonResult;
- var result = actionResult?.Value as AppSettings;
- Assert.IsTrue(result?.UseSystemTrash);
- }
-
- [TestMethod]
- public async Task UpdateAppSettings_Verbose_IgnoreSystemTrashValue()
- {
- var appSettings = new AppSettings();
- var storage = new FakeIStorage(new List { "/" });
- var controller = new AppSettingsController(appSettings,
- new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(storage)));
-
- var actionResult =
- await controller.UpdateAppSettings(new AppSettingsTransferObject { Verbose = true })
- as JsonResult;
- var result = actionResult?.Value as AppSettings;
-
- Assert.AreEqual(appSettings.UseSystemTrash, result?.UseSystemTrash);
- }
+ [TestMethod]
+ public async Task UpdateAppSettings_AllowedTypesThumb_ReturnsBadRequest()
+ {
+ // Arrange
+ var appSettings = new AppSettings();
+ var controller = new AppSettingsController(appSettings,
+ new UpdateAppSettingsByPath(appSettings, new FakeSelectorStorage(new FakeIStorage())));
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = await controller.UpdateAppSettings(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(result);
}
}
diff --git a/starsky/starskytest/Controllers/CacheIndexControllerTest.cs b/starsky/starskytest/Controllers/CacheIndexControllerTest.cs
index 841639ca04..b303ebcf1d 100644
--- a/starsky/starskytest/Controllers/CacheIndexControllerTest.cs
+++ b/starsky/starskytest/Controllers/CacheIndexControllerTest.cs
@@ -21,197 +21,225 @@
using starskytest.FakeCreateAn;
using starskytest.FakeMocks;
+namespace starskytest.Controllers;
-namespace starskytest.Controllers
+[TestClass]
+public sealed class CacheIndexControllerTest
{
- [TestClass]
- public sealed class CacheIndexControllerTest
+ private readonly AppSettings _appSettings;
+ private readonly ApplicationDbContext _context;
+ private readonly Query _query;
+
+ public CacheIndexControllerTest()
+ {
+ var provider = new ServiceCollection()
+ .AddMemoryCache()
+ .BuildServiceProvider();
+ var memoryCache = provider.GetService();
+
+ var builderDb = new DbContextOptionsBuilder();
+ builderDb.UseInMemoryDatabase("test1234");
+ var options = builderDb.Options;
+ _context = new ApplicationDbContext(options);
+ _query = new Query(_context, new AppSettings(), null!, new FakeIWebLogger(),
+ memoryCache);
+
+ // Inject Fake ExifTool; dependency injection
+ var services = new ServiceCollection();
+
+ // Fake the readMeta output
+ services.AddSingleton();
+
+ // Inject Config helper
+ services.AddSingleton(new ConfigurationBuilder().Build());
+ // random config
+ var createAnImage = new CreateAnImage();
+ var dict = new Dictionary
+ {
+ { "App:StorageFolder", createAnImage.BasePath },
+ { "App:ThumbnailTempFolder", createAnImage.BasePath },
+ { "App:Verbose", "true" }
+ };
+ // Start using dependency injection
+ var builder = new ConfigurationBuilder();
+ // Add random config to dependency injection
+ builder.AddInMemoryCollection(dict);
+ // build config
+ var configuration = builder.Build();
+ // inject config as object to a service
+ services.ConfigurePoCo(configuration.GetSection("App"));
+
+ // Add Background services
+ services.AddSingleton();
+ services.AddSingleton();
+
+ // build the service
+ var serviceProvider = services.BuildServiceProvider();
+ // get the service
+ _appSettings = serviceProvider.GetRequiredService();
+ }
+
+ [TestMethod]
+ public async Task CacheIndexController_CheckIfCacheIsRemoved_CleanCache()
{
- private readonly Query _query;
- private readonly AppSettings _appSettings;
- private readonly ApplicationDbContext _context;
+ // Act
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- public CacheIndexControllerTest()
+ await _query.AddItemAsync(new FileIndexItem
{
- var provider = new ServiceCollection()
- .AddMemoryCache()
- .BuildServiceProvider();
- var memoryCache = provider.GetService();
-
- var builderDb = new DbContextOptionsBuilder();
- builderDb.UseInMemoryDatabase("test1234");
- var options = builderDb.Options;
- _context = new ApplicationDbContext(options);
- _query = new Query(_context, new AppSettings(), null!, new FakeIWebLogger(),
- memoryCache);
-
- // Inject Fake ExifTool; dependency injection
- var services = new ServiceCollection();
-
- // Fake the readMeta output
- services.AddSingleton();
-
- // Inject Config helper
- services.AddSingleton(new ConfigurationBuilder().Build());
- // random config
- var createAnImage = new CreateAnImage();
- var dict = new Dictionary
- {
- { "App:StorageFolder", createAnImage.BasePath },
- { "App:ThumbnailTempFolder", createAnImage.BasePath },
- { "App:Verbose", "true" }
- };
- // Start using dependency injection
- var builder = new ConfigurationBuilder();
- // Add random config to dependency injection
- builder.AddInMemoryCollection(dict);
- // build config
- var configuration = builder.Build();
- // inject config as object to a service
- services.ConfigurePoCo(configuration.GetSection("App"));
-
- // Add Background services
- services.AddSingleton();
- services.AddSingleton();
-
- // build the service
- var serviceProvider = services.BuildServiceProvider();
- // get the service
- _appSettings = serviceProvider.GetRequiredService();
- }
-
- [TestMethod]
- public async Task CacheIndexController_CheckIfCacheIsRemoved_CleanCache()
+ FileName = "cacheDeleteTest", ParentDirectory = "/", IsDirectory = true
+ });
+
+ await _query.AddItemAsync(new FileIndexItem
{
- // Act
- var controller = new CacheIndexController(_query, _appSettings);
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ FileName = "file.jpg", ParentDirectory = "/cacheDeleteTest", IsDirectory = false
+ });
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = "cacheDeleteTest", ParentDirectory = "/", IsDirectory = true
- });
+ Assert.IsTrue(_query.DisplayFileFolders("/cacheDeleteTest").Any());
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = "file.jpg", ParentDirectory = "/cacheDeleteTest", IsDirectory = false
- });
+ // Ask the cache
+ _query.DisplayFileFolders("/cacheDeleteTest");
- Assert.IsTrue(_query.DisplayFileFolders("/cacheDeleteTest").Any());
+ // Don't notify the cache that there is an update
+ var newItem = new FileIndexItem
+ {
+ FileName = "file2.jpg", ParentDirectory = "/cacheDeleteTest", IsDirectory = false
+ };
+ _context.FileIndex.Add(newItem);
+ _context.SaveChanges();
+ // Write changes to database
+
+ // Check if there is one item in the cache
+ var beforeQuery = _query.DisplayFileFolders("/cacheDeleteTest");
+ Assert.AreEqual(1, beforeQuery.Count());
+
+ // Act, remove content from cache
+ var actionResult = controller.RemoveCache("/cacheDeleteTest") as JsonResult;
+ Assert.AreEqual("cache successful cleared", actionResult?.Value);
+
+ // Check if there are now two items in the cache
+ var newQuery = _query.DisplayFileFolders("/cacheDeleteTest");
+ Assert.AreEqual(2, newQuery.Count());
+ }
- // Ask the cache
- _query.DisplayFileFolders("/cacheDeleteTest");
+ [TestMethod]
+ public async Task RemoveCache_CacheDidNotExist()
+ {
+ // Act
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- // Don't notify the cache that there is an update
- var newItem = new FileIndexItem
- {
- FileName = "file2.jpg",
- ParentDirectory = "/cacheDeleteTest",
- IsDirectory = false
- };
- _context.FileIndex.Add(newItem);
- _context.SaveChanges();
- // Write changes to database
-
- // Check if there is one item in the cache
- var beforeQuery = _query.DisplayFileFolders("/cacheDeleteTest");
- Assert.AreEqual(1, beforeQuery.Count());
-
- // Act, remove content from cache
- var actionResult = controller.RemoveCache("/cacheDeleteTest") as JsonResult;
- Assert.AreEqual("cache successful cleared", actionResult?.Value);
-
- // Check if there are now two items in the cache
- var newQuery = _query.DisplayFileFolders("/cacheDeleteTest");
- Assert.AreEqual(2, newQuery.Count());
- }
-
- [TestMethod]
- public async Task RemoveCache_CacheDidNotExist()
+ await _query.AddItemAsync(new FileIndexItem
{
- // Act
- var controller = new CacheIndexController(_query, _appSettings);
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ FileName = "cacheDeleteTest2", ParentDirectory = "/", IsDirectory = true
+ });
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = "cacheDeleteTest2", ParentDirectory = "/", IsDirectory = true
- });
+ // Act, remove content from cache
+ var actionResult = controller.RemoveCache("/cacheDeleteTest2") as JsonResult;
+ Assert.AreEqual("cache did not exist", actionResult?.Value);
+ }
- // Act, remove content from cache
- var actionResult = controller.RemoveCache("/cacheDeleteTest2") as JsonResult;
- Assert.AreEqual("cache did not exist", actionResult?.Value);
- }
+ [TestMethod]
+ public void RemoveCache_ReturnsBadRequest()
+ {
+ // Arrange
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- [TestMethod]
- public void CacheIndexController_NonExistingCacheRemove()
- {
- // Act
- var controller = new CacheIndexController(_query, _appSettings);
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
- var actionResult = controller.RemoveCache("/404page") as BadRequestObjectResult;
- Assert.AreEqual(400, actionResult?.StatusCode);
- }
+ // Act
+ var result = controller.RemoveCache(null!);
- [TestMethod]
- public void CacheIndexController_CacheDisabled()
- {
- var controller =
- new CacheIndexController(_query, new AppSettings { AddMemoryCache = false });
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ // Assert
+ Assert.IsInstanceOfType(result);
+ }
- var actionResult = controller.RemoveCache("/404page") as JsonResult;
- Assert.AreEqual("cache disabled in config", actionResult?.Value);
- }
+ [TestMethod]
+ public void CacheIndexController_NonExistingCacheRemove()
+ {
+ // Act
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- [TestMethod]
- public void ListCache_CacheDidNotExist()
- {
- // Act
- var controller = new CacheIndexController(_query, _appSettings);
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
-
- // Act, remove content from cache
- var actionResult = controller.ListCache("/cacheDeleteTest2") as BadRequestObjectResult;
- Assert.AreEqual("ignored, please check if the 'f' path " +
- "exist or use a folder string to get the cache", actionResult?.Value);
- }
-
- [TestMethod]
- public void ListCache_CacheDisabled()
- {
- var controller =
- new CacheIndexController(_query, new AppSettings { AddMemoryCache = false });
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ var actionResult = controller.RemoveCache("/404page") as BadRequestObjectResult;
+ Assert.AreEqual(400, actionResult?.StatusCode);
+ }
+
+ [TestMethod]
+ public void CacheIndexController_CacheDisabled()
+ {
+ var controller =
+ new CacheIndexController(_query, new AppSettings { AddMemoryCache = false });
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
- var actionResult = controller.ListCache("/404page") as JsonResult;
- Assert.AreEqual("cache disabled in config", actionResult?.Value);
- }
+ var actionResult = controller.RemoveCache("/404page") as JsonResult;
+ Assert.AreEqual("cache disabled in config", actionResult?.Value);
+ }
- [TestMethod]
- public void ListCache_GetCache()
- {
- // Act
- var controller = new CacheIndexController(_query, _appSettings);
- controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ [TestMethod]
+ public void ListCache_ReturnsBadRequest()
+ {
+ // Arrange
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = controller.ListCache(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(result);
+ }
+
+ [TestMethod]
+ public void ListCache_CacheDidNotExist()
+ {
+ // Act
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+
+ // Act, remove content from cache
+ var actionResult = controller.ListCache("/cacheDeleteTest2") as BadRequestObjectResult;
+ Assert.AreEqual("ignored, please check if the 'f' path " +
+ "exist or use a folder string to get the cache", actionResult?.Value);
+ }
+
+ [TestMethod]
+ public void ListCache_CacheDisabled()
+ {
+ var controller =
+ new CacheIndexController(_query, new AppSettings { AddMemoryCache = false });
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+
+ var actionResult = controller.ListCache("/404page") as JsonResult;
+ Assert.AreEqual("cache disabled in config", actionResult?.Value);
+ }
- _query.AddCacheParentItem("/list-cache",
- new List
+ [TestMethod]
+ public void ListCache_GetCache()
+ {
+ // Act
+ var controller = new CacheIndexController(_query, _appSettings);
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+
+ _query.AddCacheParentItem("/list-cache",
+ new List
+ {
+ new()
{
- new FileIndexItem
- {
- FileName = "cacheDeleteTest2",
- ParentDirectory = "/list-cache",
- IsDirectory = true
- }
- });
-
- // Act, remove content from cache
- var actionResult = controller.ListCache("/list-cache") as JsonResult;
-
- Assert.IsNotNull(actionResult);
- Assert.IsNotNull(actionResult.Value);
- }
+ FileName = "cacheDeleteTest2",
+ ParentDirectory = "/list-cache",
+ IsDirectory = true
+ }
+ });
+
+ // Act, remove content from cache
+ var actionResult = controller.ListCache("/list-cache") as JsonResult;
+
+ Assert.IsNotNull(actionResult);
+ Assert.IsNotNull(actionResult.Value);
}
}
diff --git a/starsky/starskytest/Controllers/DeleteControllerTest.cs b/starsky/starskytest/Controllers/DeleteControllerTest.cs
index e855bfd09a..8627599d4f 100644
--- a/starsky/starskytest/Controllers/DeleteControllerTest.cs
+++ b/starsky/starskytest/Controllers/DeleteControllerTest.cs
@@ -26,169 +26,195 @@
using starskytest.FakeCreateAn;
using starskytest.FakeMocks;
-namespace starskytest.Controllers
+namespace starskytest.Controllers;
+
+[TestClass]
+public sealed class DeleteControllerTest
{
- [TestClass]
- public sealed class DeleteControllerTest
+ private readonly AppSettings _appSettings;
+ private readonly CreateAnImage _createAnImage;
+ private readonly IStorage _iStorage;
+
+ private readonly Query _query;
+
+ public DeleteControllerTest()
{
-
- private readonly Query _query;
- private readonly AppSettings _appSettings;
- private readonly CreateAnImage _createAnImage;
- private readonly IStorage _iStorage;
+ var provider = new ServiceCollection()
+ .AddMemoryCache()
+ .BuildServiceProvider();
+ var memoryCache = provider.GetService();
+
+ var builderDb = new DbContextOptionsBuilder();
+ builderDb.UseInMemoryDatabase("test1234");
+ var options = builderDb.Options;
+ var context = new ApplicationDbContext(options);
+ _query = new Query(context,
+ new AppSettings(), null, new FakeIWebLogger(), memoryCache);
- public DeleteControllerTest()
+ // Inject Fake ExifTool; dependency injection
+ var services = new ServiceCollection();
+
+ // Fake the readMeta output
+ services.AddSingleton();
+
+ // Inject Config helper
+ services.AddSingleton(new ConfigurationBuilder().Build());
+ // random config
+ _createAnImage = new CreateAnImage();
+ var dict = new Dictionary
{
- var provider = new ServiceCollection()
- .AddMemoryCache()
- .BuildServiceProvider();
- var memoryCache = provider.GetService();
-
- var builderDb = new DbContextOptionsBuilder();
- builderDb.UseInMemoryDatabase("test1234");
- var options = builderDb.Options;
- var context = new ApplicationDbContext(options);
- _query = new Query(context,
- new AppSettings(), null, new FakeIWebLogger(),memoryCache);
-
- // Inject Fake ExifTool; dependency injection
- var services = new ServiceCollection();
-
- // Fake the readMeta output
- services.AddSingleton();
-
- // Inject Config helper
- services.AddSingleton(new ConfigurationBuilder().Build());
- // random config
- _createAnImage = new CreateAnImage();
- var dict = new Dictionary
- {
- { "App:StorageFolder", _createAnImage.BasePath },
- { "App:ThumbnailTempFolder",_createAnImage.BasePath },
- { "App:Verbose", "true" }
- };
- // Start using dependency injection
- var builder = new ConfigurationBuilder();
- // Add random config to dependency injection
- builder.AddInMemoryCollection(dict);
- // build config
- var configuration = builder.Build();
- // inject config as object to a service
- services.ConfigurePoCo(configuration.GetSection("App"));
-
- // Add Background services
- services.AddSingleton();
- services.AddSingleton();
-
- // build the service
- var serviceProvider = services.BuildServiceProvider();
- // get the service
- _appSettings = serviceProvider.GetRequiredService();
-
- _iStorage = new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger());
- }
-
- private async Task InsertSearchData(bool delete = false)
+ { "App:StorageFolder", _createAnImage.BasePath },
+ { "App:ThumbnailTempFolder", _createAnImage.BasePath },
+ { "App:Verbose", "true" }
+ };
+ // Start using dependency injection
+ var builder = new ConfigurationBuilder();
+ // Add random config to dependency injection
+ builder.AddInMemoryCollection(dict);
+ // build config
+ var configuration = builder.Build();
+ // inject config as object to a service
+ services.ConfigurePoCo(configuration.GetSection("App"));
+
+ // Add Background services
+ services.AddSingleton();
+ services.AddSingleton();
+
+ // build the service
+ var serviceProvider = services.BuildServiceProvider();
+ // get the service
+ _appSettings = serviceProvider.GetRequiredService();
+
+ _iStorage = new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger());
+ }
+
+ private async Task InsertSearchData(bool delete = false)
+ {
+ var fileHashCode = new FileHash(_iStorage).GetHashCode(_createAnImage.DbPath).Key;
+
+ if ( string.IsNullOrEmpty(await _query.GetSubPathByHashAsync(fileHashCode)) )
{
- var fileHashCode = new FileHash(_iStorage).GetHashCode(_createAnImage.DbPath).Key;
-
- if (string.IsNullOrEmpty(await _query.GetSubPathByHashAsync(fileHashCode)))
+ var isDelete = string.Empty;
+ if ( delete )
{
- var isDelete = string.Empty;
- if (delete) isDelete = TrashKeyword.TrashKeywordString;
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = _createAnImage.FileName,
- ParentDirectory = "/",
- FileHash = fileHashCode,
- ColorClass = ColorClassParser.Color.Winner, // 1
- Tags = isDelete
- });
+ isDelete = TrashKeyword.TrashKeywordString;
}
- return _query.GetObjectByFilePath(_createAnImage.DbPath);
- }
-
- [TestMethod]
- public async Task ApiController_Delete_API_HappyFlow_Test()
- {
- var createAnImage = await InsertSearchData(true);
- _appSettings.DatabaseType = AppSettings.DatabaseTypeList.InMemoryDatabase;
-
- // RealFs Storage
- var selectorStorage = new FakeSelectorStorage(new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
-
- var deleteItem = new DeleteItem(_query,_appSettings,selectorStorage);
- var controller = new DeleteController(deleteItem);
-
- Console.WriteLine("createAnImage.FilePath");
- Console.WriteLine("@#~ "+ createAnImage?.FilePath);
-
- // create an image
- var createAnImage1 = new CreateAnImage();
- Assert.IsNotNull(createAnImage1);
-
- var actionResult = await controller.Delete(createAnImage?.FilePath!) as JsonResult;
- Assert.AreNotEqual(null,actionResult);
- var jsonCollection = actionResult?.Value as List;
- Assert.AreEqual(createAnImage?.FilePath,jsonCollection?.FirstOrDefault()?.FilePath);
-
- var createAnImage2 = new CreateAnImage(); //restore afterwards
- Assert.IsNotNull(createAnImage2);
- }
-
- [TestMethod]
- public async Task ApiController_Delete_API_RemoveNotAllowedFile_Test()
- {
- // re add data
- var createAnImage = await InsertSearchData();
- Assert.IsNotNull(createAnImage?.FilePath);
-
- // Clean existing items to avoid errors
- var itemByHash = _query.SingleItem(createAnImage.FilePath);
- Assert.IsNotNull(itemByHash);
- Assert.IsNotNull(itemByHash.FileIndexItem);
-
- itemByHash.FileIndexItem.Tags = string.Empty;
- await _query.UpdateItemAsync(itemByHash.FileIndexItem);
-
- _appSettings.DatabaseType = AppSettings.DatabaseTypeList.InMemoryDatabase;
-
- var selectorStorage =
- new FakeSelectorStorage(new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
-
- var deleteItem = new DeleteItem(_query,_appSettings,selectorStorage);
- var controller = new DeleteController(deleteItem);
-
- var notFoundResult = await controller.Delete(createAnImage.FilePath) as NotFoundObjectResult;
- Assert.AreEqual(404,notFoundResult?.StatusCode);
- var jsonCollection = notFoundResult?.Value as List;
-
- Assert.AreEqual(FileIndexItem.ExifStatus.OperationNotSupported,
- jsonCollection?.FirstOrDefault()?.Status);
-
- await _query.RemoveItemAsync(_query.SingleItem(createAnImage.FilePath)?.FileIndexItem!);
- }
-
-
- [TestMethod]
- public async Task ApiController_Delete_SourceImageMissingOnDisk_WithFakeExiftool()
- {
await _query.AddItemAsync(new FileIndexItem
{
- FileName = "345678765434567.jpg",
+ FileName = _createAnImage.FileName,
ParentDirectory = "/",
- FileHash = "345678765434567"
+ FileHash = fileHashCode,
+ ColorClass = ColorClassParser.Color.Winner, // 1
+ Tags = isDelete
});
-
- var selectorStorage = new FakeSelectorStorage(new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
- var deleteItem = new DeleteItem(_query,_appSettings,selectorStorage);
- var controller = new DeleteController(deleteItem);
- var notFoundResult = await controller.Delete("/345678765434567.jpg") as NotFoundObjectResult;
- Assert.AreEqual(404,notFoundResult?.StatusCode);
-
- await _query.RemoveItemAsync(_query.SingleItem("/345678765434567.jpg")?.FileIndexItem!);
}
+ return _query.GetObjectByFilePath(_createAnImage.DbPath);
+ }
+
+
+ [TestMethod]
+ public async Task ApiController_Delete_API_HappyFlow_Test()
+ {
+ var createAnImage = await InsertSearchData(true);
+ _appSettings.DatabaseType = AppSettings.DatabaseTypeList.InMemoryDatabase;
+
+ // RealFs Storage
+ var selectorStorage =
+ new FakeSelectorStorage(
+ new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
+
+ var deleteItem = new DeleteItem(_query, _appSettings, selectorStorage);
+ var controller = new DeleteController(deleteItem);
+
+ Console.WriteLine("createAnImage.FilePath");
+ Console.WriteLine("@#~ " + createAnImage?.FilePath);
+
+ // create an image
+ var createAnImage1 = new CreateAnImage();
+ Assert.IsNotNull(createAnImage1);
+
+ var actionResult = await controller.Delete(createAnImage?.FilePath!) as JsonResult;
+ Assert.AreNotEqual(null, actionResult);
+ var jsonCollection = actionResult?.Value as List;
+ Assert.AreEqual(createAnImage?.FilePath, jsonCollection?.FirstOrDefault()?.FilePath);
+
+ var createAnImage2 = new CreateAnImage(); //restore afterwards
+ Assert.IsNotNull(createAnImage2);
+ }
+
+ [TestMethod]
+ public async Task Delete_ReturnsBadRequest()
+ {
+ // Arrange
+ var deleteItem = new DeleteItem(_query, _appSettings, new FakeSelectorStorage());
+ var controller = new DeleteController(deleteItem);
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = await controller.Delete(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(result);
+ }
+
+ [TestMethod]
+ public async Task ApiController_Delete_API_RemoveNotAllowedFile_Test()
+ {
+ // re add data
+ var createAnImage = await InsertSearchData();
+ Assert.IsNotNull(createAnImage?.FilePath);
+
+ // Clean existing items to avoid errors
+ var itemByHash = _query.SingleItem(createAnImage.FilePath);
+ Assert.IsNotNull(itemByHash);
+ Assert.IsNotNull(itemByHash.FileIndexItem);
+
+ itemByHash.FileIndexItem.Tags = string.Empty;
+ await _query.UpdateItemAsync(itemByHash.FileIndexItem);
+
+ _appSettings.DatabaseType = AppSettings.DatabaseTypeList.InMemoryDatabase;
+
+ var selectorStorage =
+ new FakeSelectorStorage(
+ new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
+
+ var deleteItem = new DeleteItem(_query, _appSettings, selectorStorage);
+ var controller = new DeleteController(deleteItem);
+
+ var notFoundResult =
+ await controller.Delete(createAnImage.FilePath) as NotFoundObjectResult;
+ Assert.AreEqual(404, notFoundResult?.StatusCode);
+ var jsonCollection = notFoundResult?.Value as List;
+
+ Assert.AreEqual(FileIndexItem.ExifStatus.OperationNotSupported,
+ jsonCollection?.FirstOrDefault()?.Status);
+
+ await _query.RemoveItemAsync(_query.SingleItem(createAnImage.FilePath)?.FileIndexItem!);
+ }
+
+
+ [TestMethod]
+ public async Task ApiController_Delete_SourceImageMissingOnDisk_WithFakeExiftool()
+ {
+ await _query.AddItemAsync(new FileIndexItem
+ {
+ FileName = "345678765434567.jpg",
+ ParentDirectory = "/",
+ FileHash = "345678765434567"
+ });
+
+ var selectorStorage =
+ new FakeSelectorStorage(
+ new StorageSubPathFilesystem(_appSettings, new FakeIWebLogger()));
+ var deleteItem = new DeleteItem(_query, _appSettings, selectorStorage);
+ var controller = new DeleteController(deleteItem);
+ var notFoundResult =
+ await controller.Delete("/345678765434567.jpg") as NotFoundObjectResult;
+ Assert.AreEqual(404, notFoundResult?.StatusCode);
+
+ await _query.RemoveItemAsync(_query.SingleItem("/345678765434567.jpg")?.FileIndexItem!);
}
}
diff --git a/starsky/starskytest/Controllers/DesktopEditorControllerTest.cs b/starsky/starskytest/Controllers/DesktopEditorControllerTest.cs
index ef09835d47..12468292ed 100644
--- a/starsky/starskytest/Controllers/DesktopEditorControllerTest.cs
+++ b/starsky/starskytest/Controllers/DesktopEditorControllerTest.cs
@@ -31,13 +31,30 @@ public void OpenAmountConfirmationChecker_FeatureToggleEnabled()
var result = controller.OpenAmountConfirmationChecker("/test.jpg;/test2.jpg");
- var castedResult = ( JsonResult )result;
- var boolValue = ( bool? )castedResult.Value;
+ var castedResult = ( JsonResult ) result;
+ var boolValue = ( bool? ) castedResult.Value;
// mock is always true
Assert.IsTrue(boolValue);
}
+ [TestMethod]
+ public void OpenAmountConfirmationChecker_ReturnsBadRequest()
+ {
+ // Arrange
+ var controller = new DesktopEditorController(new OpenEditorDesktopService(new AppSettings(),
+ new FakeIOpenApplicationNativeService(new List(), "test"),
+ new FakeIOpenEditorPreflight(new List())));
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = controller.OpenAmountConfirmationChecker(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(result);
+ }
+
[TestMethod]
public async Task OpenAsync_FeatureToggleDisabled()
{
@@ -51,11 +68,28 @@ public async Task OpenAsync_FeatureToggleDisabled()
};
var result = await controller.OpenAsync("/test.jpg;/test2.jpg");
- var castedResult = ( BadRequestObjectResult )result;
+ var castedResult = ( BadRequestObjectResult ) result;
Assert.AreEqual(400, castedResult.StatusCode);
}
+ [TestMethod]
+ public async Task OpenAsync_ReturnsBadRequest()
+ {
+ // Arrange
+ var controller = new DesktopEditorController(new OpenEditorDesktopService(new AppSettings(),
+ new FakeIOpenApplicationNativeService(new List(), "test"),
+ new FakeIOpenEditorPreflight(new List())));
+
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ // Act
+ var result = await controller.OpenAsync(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(result);
+ }
+
[TestMethod]
public async Task OpenAsync_NoResultsBack()
{
@@ -72,8 +106,8 @@ public async Task OpenAsync_NoResultsBack()
var result = await controller.OpenAsync("/test.jpg;/test2.jpg");
Assert.AreEqual(206, controller.HttpContext.Response.StatusCode);
- var castedResult = ( JsonResult )result;
- var arrayValues = ( List? )castedResult.Value;
+ var castedResult = ( JsonResult ) result;
+ var arrayValues = ( List? ) castedResult.Value;
Assert.AreEqual(0, arrayValues?.Count);
}
@@ -83,7 +117,7 @@ public async Task OpenAsync_HappyFlow()
{
var preflight = new FakeIOpenEditorPreflight(new List
{
- new PathImageFormatExistsAppPathModel
+ new()
{
AppPath = "test",
Status = FileIndexItem.ExifStatus.Ok,
@@ -105,8 +139,8 @@ public async Task OpenAsync_HappyFlow()
var result = await controller.OpenAsync("/test.jpg;/test2.jpg");
Assert.AreEqual(200, controller.HttpContext.Response.StatusCode);
- var castedResult = ( JsonResult )result;
- var arrayValues = ( List? )castedResult.Value;
+ var castedResult = ( JsonResult ) result;
+ var arrayValues = ( List? ) castedResult.Value;
Assert.AreEqual(1, arrayValues?.Count);
}
diff --git a/starsky/starskytest/Controllers/DiskControllerTest.cs b/starsky/starskytest/Controllers/DiskControllerTest.cs
index 72e2471710..b6c34d5593 100644
--- a/starsky/starskytest/Controllers/DiskControllerTest.cs
+++ b/starsky/starskytest/Controllers/DiskControllerTest.cs
@@ -26,297 +26,315 @@
using starskytest.FakeCreateAn;
using starskytest.FakeMocks;
-namespace starskytest.Controllers
+namespace starskytest.Controllers;
+
+[TestClass]
+public sealed class DiskControllerTest
{
- [TestClass]
- public sealed class DiskControllerTest
+ private readonly CreateAnImage _createAnImage;
+ private readonly Query _query;
+ private IStorage? _iStorage;
+
+ public DiskControllerTest()
{
- private readonly Query _query;
- private readonly CreateAnImage _createAnImage;
- private IStorage? _iStorage;
+ var provider = new ServiceCollection()
+ .AddMemoryCache()
+ .BuildServiceProvider();
+ var memoryCache = provider.GetService();
- public DiskControllerTest()
- {
- var provider = new ServiceCollection()
- .AddMemoryCache()
- .BuildServiceProvider();
- var memoryCache = provider.GetService();
+ var builderDb = new DbContextOptionsBuilder();
+ builderDb.UseInMemoryDatabase("SyncControllerTest");
+ var options = builderDb.Options;
+ var context = new ApplicationDbContext(options);
- var builderDb = new DbContextOptionsBuilder();
- builderDb.UseInMemoryDatabase("SyncControllerTest");
- var options = builderDb.Options;
- var context = new ApplicationDbContext(options);
+ // Inject Fake Exiftool; dependency injection
+ var services = new ServiceCollection();
+ services.AddSingleton();
- // Inject Fake Exiftool; dependency injection
- var services = new ServiceCollection();
- services.AddSingleton();
+ // Fake the readmeta output
+ services.AddSingleton();
- // Fake the readmeta output
- services.AddSingleton();
+ // Inject Config helper
+ services.AddSingleton(new ConfigurationBuilder().Build());
+ // random config
+ _createAnImage = new CreateAnImage();
+ var dict = new Dictionary
+ {
+ { "App:StorageFolder", _createAnImage.BasePath },
+ { "App:ThumbnailTempFolder", _createAnImage.BasePath },
+ { "App:Verbose", "true" }
+ };
+ // Start using dependency injection
+ var builder = new ConfigurationBuilder();
+ // Add random config to dependency injection
+ builder.AddInMemoryCollection(dict);
+ // build config
+ var configuration = builder.Build();
+ // inject config as object to a service
+ services.ConfigurePoCo(configuration.GetSection("App"));
+
+ // Add Background services
+ services.AddSingleton();
+ services.AddSingleton();
+
+ // build the service
+ var serviceProvider = services.BuildServiceProvider();
+ // get the service
+ var appSettings = serviceProvider.GetRequiredService();
+
+ var scopeFactory = serviceProvider.GetRequiredService();
+ _query = new Query(context, appSettings, scopeFactory, new FakeIWebLogger(),
+ memoryCache);
+ }
- // Inject Config helper
- services.AddSingleton(new ConfigurationBuilder().Build());
- // random config
- _createAnImage = new CreateAnImage();
- var dict = new Dictionary
- {
- { "App:StorageFolder", _createAnImage.BasePath },
- { "App:ThumbnailTempFolder", _createAnImage.BasePath },
- { "App:Verbose", "true" }
- };
- // Start using dependency injection
- var builder = new ConfigurationBuilder();
- // Add random config to dependency injection
- builder.AddInMemoryCollection(dict!);
- // build config
- var configuration = builder.Build();
- // inject config as object to a service
- services.ConfigurePoCo(configuration.GetSection("App"));
-
- // Add Background services
- services.AddSingleton();
- services.AddSingleton();
-
- // build the service
- var serviceProvider = services.BuildServiceProvider();
- // get the service
- var appSettings = serviceProvider.GetRequiredService();
-
- var scopeFactory = serviceProvider.GetRequiredService();
- _query = new Query(context, appSettings, scopeFactory, new FakeIWebLogger(),
- memoryCache);
- }
+ private async Task InsertSearchData()
+ {
+ _iStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var fileHashCode =
+ ( await new FileHash(_iStorage).GetHashCodeAsync(_createAnImage.DbPath) ).Key;
- private async Task InsertSearchData()
+ if ( string.IsNullOrEmpty(await _query.GetSubPathByHashAsync(fileHashCode)) )
{
- _iStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var fileHashCode =
- ( await new FileHash(_iStorage).GetHashCodeAsync(_createAnImage.DbPath) ).Key;
+ await _query.AddItemAsync(new FileIndexItem
+ {
+ FileName = "/", ParentDirectory = "/", IsDirectory = true
+ });
- if ( string.IsNullOrEmpty(await _query.GetSubPathByHashAsync(fileHashCode)) )
+ await _query.AddItemAsync(new FileIndexItem
{
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = "/", ParentDirectory = "/", IsDirectory = true
- });
-
- await _query.AddItemAsync(new FileIndexItem
- {
- FileName = _createAnImage.FileName,
- ParentDirectory = "/",
- FileHash = fileHashCode,
- ColorClass = ColorClassParser.Color.Winner, // 1
- });
- }
-
- _query.GetObjectByFilePath(_createAnImage.DbPath);
+ FileName = _createAnImage.FileName,
+ ParentDirectory = "/",
+ FileHash = fileHashCode,
+ ColorClass = ColorClassParser.Color.Winner // 1
+ });
}
+ await _query.GetObjectByFilePathAsync(_createAnImage.DbPath);
+ }
- [TestMethod]
- public async Task SyncControllerTest_Rename_NotFoundInIndex()
- {
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- var fakeStorage = new FakeIStorage();
- var storageSelector = new FakeSelectorStorage(fakeStorage);
- var controller = new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery());
- controller.ControllerContext = context;
+ [TestMethod]
+ public async Task SyncControllerTest_Rename_NotFoundInIndex()
+ {
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var fakeStorage = new FakeIStorage();
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var result =
- await controller.Rename("/notfound-image.jpg", "/test.jpg") as NotFoundObjectResult;
+ var controller = new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery());
+ controller.ControllerContext = context;
- Assert.AreEqual(404, result?.StatusCode);
- }
+ var result =
+ await controller.Rename("/notfound-image.jpg", "/test.jpg") as NotFoundObjectResult;
- [TestMethod]
- public async Task SyncControllerTest_BadRequest()
- {
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- var fakeStorage = new FakeIStorage();
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ Assert.AreEqual(404, result?.StatusCode);
+ }
- var controller = new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery());
- controller.ControllerContext = context;
+ [TestMethod]
+ public async Task Rename_BadRequest()
+ {
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var fakeStorage = new FakeIStorage();
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var result =
- await controller.Rename(string.Empty, "/test.jpg") as BadRequestObjectResult;
+ var controller = new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery());
+ controller.ControllerContext = context;
- Assert.AreEqual(400, result?.StatusCode);
- }
+ var result =
+ await controller.Rename(string.Empty, "/test.jpg") as BadRequestObjectResult;
- [TestMethod]
- public async Task SyncControllerTest_Rename_Good()
- {
- await InsertSearchData();
+ Assert.AreEqual(400, result?.StatusCode);
+ }
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ [TestMethod]
+ public async Task Rename_ReturnsBadRequest()
+ {
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var fakeStorage = new FakeIStorage();
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var fakeStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ var controller = new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery());
+ controller.ControllerContext = context;
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
- var controller =
- new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
- {
- ControllerContext = context
- };
+ var result =
+ await controller.Rename(string.Empty, "/test.jpg") as BadRequestObjectResult;
- var result = await controller.Rename(_createAnImage.DbPath, "/test.jpg") as JsonResult;
- var list = result?.Value as List;
+ Assert.AreEqual(400, result?.StatusCode);
+ Assert.IsInstanceOfType(result);
+ }
- Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?.FirstOrDefault()?.Status);
+ [TestMethod]
+ public async Task SyncControllerTest_Rename_Good()
+ {
+ await InsertSearchData();
- await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
- }
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- [TestMethod]
- public async Task SyncControllerTest_Rename_WithCurrentStatusDisabled()
- {
- await InsertSearchData();
+ var fakeStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var controller =
+ new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
+ {
+ ControllerContext = context
+ };
- var fakeStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ var result = await controller.Rename(_createAnImage.DbPath, "/test.jpg") as JsonResult;
+ var list = result?.Value as List;
- var controller =
- new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
- {
- ControllerContext = context
- };
+ Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?.FirstOrDefault()?.Status);
- var result =
- await controller.Rename(_createAnImage.DbPath, "/test.jpg", true, false) as
- JsonResult;
- var list = result?.Value as List;
+ await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
+ }
- Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?[0].Status);
- Assert.AreEqual(FileIndexItem.ExifStatus.NotFoundSourceMissing, list?[1].Status);
+ [TestMethod]
+ public async Task SyncControllerTest_Rename_WithCurrentStatusDisabled()
+ {
+ await InsertSearchData();
- await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
- }
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- [TestMethod]
- public async Task SyncControllerTest_Rename_Good_SocketUpdate()
- {
- await InsertSearchData();
+ var fakeStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- var socket = new FakeIWebSocketConnectionsService();
+ var controller =
+ new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
+ {
+ ControllerContext = context
+ };
- var fakeStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ var result =
+ await controller.Rename(_createAnImage.DbPath, "/test.jpg", true, false) as
+ JsonResult;
+ var list = result?.Value as List;
- var controller =
- new DiskController(_query, storageSelector,
- socket, new FakeINotificationQuery()) { ControllerContext = context };
+ Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?[0].Status);
+ Assert.AreEqual(FileIndexItem.ExifStatus.NotFoundSourceMissing, list?[1].Status);
- await controller.Rename(_createAnImage.DbPath, "/test.jpg");
+ await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
+ }
- Assert.AreEqual(1, socket.FakeSendToAllAsync.Count(p => !p.Contains("[system]")));
- Assert.IsTrue(socket.FakeSendToAllAsync[0].Contains("/test.jpg"));
+ [TestMethod]
+ public async Task SyncControllerTest_Rename_Good_SocketUpdate()
+ {
+ await InsertSearchData();
- await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
- }
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var socket = new FakeIWebSocketConnectionsService();
- [TestMethod]
- public async Task SyncControllerTest_Mkdir_Good()
- {
- await InsertSearchData();
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
-
- var fakeStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
-
- var controller =
- new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
- {
- ControllerContext = context
- };
-
- var result = await controller.Mkdir("/test_dir") as JsonResult;
- var list = result?.Value as List;
- Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?.FirstOrDefault()?.Status);
- }
+ var fakeStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- [TestMethod]
- public async Task SyncControllerTest_Mkdir_Good_SocketUpdate()
- {
- await InsertSearchData();
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ var controller =
+ new DiskController(_query, storageSelector,
+ socket, new FakeINotificationQuery()) { ControllerContext = context };
- var socket = new FakeIWebSocketConnectionsService();
- var fakeStorage = new FakeIStorage(new List { "/" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ await controller.Rename(_createAnImage.DbPath, "/test.jpg");
- var controller =
- new DiskController(_query, storageSelector,
- socket, new FakeINotificationQuery()) { ControllerContext = context };
+ Assert.AreEqual(1, socket.FakeSendToAllAsync.Count(p => !p.Contains("[system]")));
+ Assert.IsTrue(socket.FakeSendToAllAsync[0].Contains("/test.jpg"));
- await controller.Mkdir("/test_dir");
+ await _query.RemoveItemAsync(( await _query.GetObjectByFilePathAsync("/test.jpg") )!);
+ }
- var value = socket.FakeSendToAllAsync.Find(p =>
- !p.StartsWith("[system]"));
+ [TestMethod]
+ public async Task SyncControllerTest_Mkdir_Good()
+ {
+ await InsertSearchData();
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- Assert.IsNotNull(value);
- Assert.IsTrue(value.Contains("/test_dir"));
- }
+ var fakeStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- [TestMethod]
- public async Task SyncControllerTest_Mkdir_Exist()
- {
- await InsertSearchData();
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
-
- var fakeStorage = new FakeIStorage(new List { "/", "/test_dir" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
-
- var controller =
- new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
- {
- ControllerContext = context
- };
-
- var result = await controller.Mkdir("/test_dir") as JsonResult;
- var list = result?.Value as List;
- Assert.AreEqual(FileIndexItem.ExifStatus.OperationNotSupported,
- list?.FirstOrDefault()?.Status);
- }
+ var controller =
+ new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
+ {
+ ControllerContext = context
+ };
+ var result = await controller.Mkdir("/test_dir") as JsonResult;
+ var list = result?.Value as List;
+ Assert.AreEqual(FileIndexItem.ExifStatus.Ok, list?.FirstOrDefault()?.Status);
+ }
- [TestMethod]
- public async Task Mkdir_BadRequest()
- {
- var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+ [TestMethod]
+ public async Task SyncControllerTest_Mkdir_Good_SocketUpdate()
+ {
+ await InsertSearchData();
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
- var fakeStorage = new FakeIStorage(new List { "/", "/test_dir" },
- new List { _createAnImage.DbPath });
- var storageSelector = new FakeSelectorStorage(fakeStorage);
+ var socket = new FakeIWebSocketConnectionsService();
+ var fakeStorage = new FakeIStorage(new List { "/" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
- var controller =
- new DiskController(_query, storageSelector,
- new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
- {
- ControllerContext = context
- };
+ var controller =
+ new DiskController(_query, storageSelector,
+ socket, new FakeINotificationQuery()) { ControllerContext = context };
- await controller.Mkdir(string.Empty);
+ await controller.Mkdir("/test_dir");
- Assert.AreEqual(400, context.HttpContext.Response.StatusCode);
- }
+ var value = socket.FakeSendToAllAsync.Find(p =>
+ !p.StartsWith("[system]"));
+
+ Assert.IsNotNull(value);
+ Assert.IsTrue(value.Contains("/test_dir"));
+ }
+
+ [TestMethod]
+ public async Task SyncControllerTest_Mkdir_Exist()
+ {
+ await InsertSearchData();
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+
+ var fakeStorage = new FakeIStorage(new List { "/", "/test_dir" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
+
+ var controller =
+ new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
+ {
+ ControllerContext = context
+ };
+
+ var result = await controller.Mkdir("/test_dir") as JsonResult;
+ var list = result?.Value as List;
+ Assert.AreEqual(FileIndexItem.ExifStatus.OperationNotSupported,
+ list?.FirstOrDefault()?.Status);
+ }
+
+
+ [TestMethod]
+ public async Task Mkdir_BadRequest()
+ {
+ var context = new ControllerContext { HttpContext = new DefaultHttpContext() };
+
+ var fakeStorage = new FakeIStorage(new List { "/", "/test_dir" },
+ new List { _createAnImage.DbPath });
+ var storageSelector = new FakeSelectorStorage(fakeStorage);
+
+ var controller =
+ new DiskController(_query, storageSelector,
+ new FakeIWebSocketConnectionsService(), new FakeINotificationQuery())
+ {
+ ControllerContext = context
+ };
+
+ await controller.Mkdir(string.Empty);
+
+ Assert.AreEqual(400, context.HttpContext.Response.StatusCode);
}
}
diff --git a/starsky/starskytest/Controllers/DownloadPhotoControllerTest.cs b/starsky/starskytest/Controllers/DownloadPhotoControllerTest.cs
index f11005c120..a0eddcfdf7 100644
--- a/starsky/starskytest/Controllers/DownloadPhotoControllerTest.cs
+++ b/starsky/starskytest/Controllers/DownloadPhotoControllerTest.cs
@@ -14,261 +14,322 @@
using starsky.foundation.database.Query;
using starsky.foundation.platform.Helpers;
using starsky.foundation.platform.Models;
+using starskytest.FakeCreateAn;
using starskytest.FakeMocks;
-namespace starskytest.Controllers
+namespace starskytest.Controllers;
+
+[TestClass]
+public sealed class DownloadPhotoControllerTest
{
- [TestClass]
- public sealed class DownloadPhotoControllerTest
+ private readonly Query _query;
+
+ public DownloadPhotoControllerTest()
{
- private readonly Query _query;
+ var provider = new ServiceCollection()
+ .AddMemoryCache()
+ .BuildServiceProvider();
+ var memoryCache = provider.GetService();
+
+ var builderDb = new DbContextOptionsBuilder();
+ builderDb.UseInMemoryDatabase(nameof(DownloadPhotoControllerTest));
+ var options = builderDb.Options;
+ var context = new ApplicationDbContext(options);
+ var scopeFactory = provider.GetService();
+ _query = new Query(context, new AppSettings(), scopeFactory, new FakeIWebLogger(),
+ memoryCache);
+ }
- public DownloadPhotoControllerTest()
+ private async Task InsertSearchData()
+ {
+ var item = new FileIndexItem
{
- var provider = new ServiceCollection()
- .AddMemoryCache()
- .BuildServiceProvider();
- var memoryCache = provider.GetService();
-
- var builderDb = new DbContextOptionsBuilder();
- builderDb.UseInMemoryDatabase(nameof(DownloadPhotoControllerTest));
- var options = builderDb.Options;
- var context = new ApplicationDbContext(options);
- var scopeFactory = provider.GetService();
- _query = new Query(context, new AppSettings(), scopeFactory, new FakeIWebLogger(), memoryCache);
- }
+ FileName = "test.jpg",
+ ParentDirectory = "/",
+ FileHash = "/home0012304590.jpg",
+ ColorClass = ColorClassParser.Color.Winner // 1
+ };
- private async Task InsertSearchData()
+ if ( string.IsNullOrEmpty(await _query.GetSubPathByHashAsync("home0012304590")) )
{
- var item = new FileIndexItem
+ await _query.AddItemAsync(item);
+ }
+
+ return item;
+ }
+
+ private static FakeIStorage ArrangeStorage()
+ {
+ var folderPaths = new List { "/" };
+ var inputSubPaths = new List { "/test.jpg", "/test.xmp", "/corrupt.jpg" };
+ var storage =
+ new FakeIStorage(folderPaths, inputSubPaths,
+ new List
+ {
+ CreateAnImage.Bytes.ToArray(),
+ CreateAnXmp.Bytes.ToArray(),
+ Array.Empty()
+ });
+ return storage;
+ }
+
+ [TestMethod]
+ public void DownloadSidecar_Ok()
+ {
+ // Arrange
+ var selectorStorage = new FakeSelectorStorage(ArrangeStorage());
+
+ // Act
+ var controller = new DownloadPhotoController(_query, selectorStorage, new FakeIWebLogger(),
+ new FakeIThumbnailService());
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ var actionResult = controller.DownloadSidecar("/test.xmp") as FileStreamResult;
+ Assert.AreNotEqual(null, actionResult);
+
+ actionResult?.FileStream.Dispose();
+ }
+
+ [TestMethod]
+ public void DownloadSidecar_ReturnsBadRequest()
+ {
+ // Arrange
+ var selectorStorage = new FakeSelectorStorage(ArrangeStorage());
+
+ // Act
+ var controller = new DownloadPhotoController(_query, selectorStorage, new FakeIWebLogger(),
+ new FakeIThumbnailService());
+ controller.ControllerContext.HttpContext = new DefaultHttpContext();
+ controller.ModelState.AddModelError("Key", "ErrorMessage");
+
+ var actionResult = controller.DownloadSidecar(null!);
+
+ // Assert
+ Assert.IsInstanceOfType(actionResult, typeof(BadRequestObjectResult));
+ }
+
+ [TestMethod]
+ public void DownloadSidecar_TryToGetJpeg()
+ {
+ // Arrange
+ var selectorStorage = new FakeSelectorStorage(ArrangeStorage());
+
+ // Act
+ var controller =
+ new DownloadPhotoController(_query, selectorStorage, new FakeIWebLogger(),
+ new FakeIThumbnailService())
{
- FileName = "test.jpg",
- ParentDirectory = "/",
- FileHash = "/home0012304590.jpg",
- ColorClass = ColorClassParser.Color.Winner // 1
+ ControllerContext = { HttpContext = new DefaultHttpContext() }
};
+ var actionResult = controller.DownloadSidecar("/test.jpg") as NotFoundObjectResult;
- if ( string.IsNullOrEmpty(await _query.GetSubPathByHashAsync("home0012304590")) )
- {
- await _query.AddItemAsync(item);
- }
- return item;
- }
+ Assert.AreNotEqual(null, actionResult);
+ Assert.AreEqual(404, actionResult?.StatusCode);
+ }
- private static FakeIStorage ArrangeStorage()
- {
- var folderPaths = new List{"/"};
- var inputSubPaths = new List