Skip to content

Commit

Permalink
Merge pull request #1441 from qdraw/feature/202403-code-smells-6
Browse files Browse the repository at this point in the history
Feature/202403 code smells 6
  • Loading branch information
qdraw authored Mar 6, 2024
2 parents b4c67b3 + d7fa128 commit 2ba54b6
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 35 deletions.
12 changes: 8 additions & 4 deletions starsky/starsky.foundation.platform/Helpers/ArgsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ public List<string> GetPathListFormArgs(IReadOnlyList<string> args)
var path = GetUserInputPathFromArg(args);

// To use only with -p or --path > current directory
if ( ( args.Contains("-p") || args.Contains("--path") ) &&
if ( ( args.Contains("-p") || args.Contains(PathCommandLineArgLong) ) &&
( path == string.Empty || path[0] == "-"[0] ) )
{
path = Directory.GetCurrentDirectory();
Expand All @@ -572,6 +572,8 @@ public List<string> GetPathListFormArgs(IReadOnlyList<string> args)
return dotCommaRegex.Split(path).Where(p => !string.IsNullOrWhiteSpace(p)).ToList();
}

private const string PathCommandLineArgLong = "--path";

/// <summary>
/// Get the user input from -p or --path
/// </summary>
Expand All @@ -582,7 +584,8 @@ private static string GetUserInputPathFromArg(IReadOnlyList<string> args)
var path = string.Empty;
for ( var arg = 0; arg < args.Count; arg++ )
{
if ( ( args[arg].Equals("--path", StringComparison.CurrentCultureIgnoreCase) ||
if ( ( args[arg].Equals(PathCommandLineArgLong,
StringComparison.CurrentCultureIgnoreCase) ||
args[arg].Equals("-p", StringComparison.CurrentCultureIgnoreCase) ) &&
( arg + 1 ) != args.Count )
{
Expand Down Expand Up @@ -671,7 +674,7 @@ public string GetPathFormArgs(IReadOnlyList<string> args, bool dbStyle = true)
var path = GetUserInputPathFromArg(args);

// To use only with -p or --path > current directory
if ( ( args.Contains("-p") || args.Contains("--path") ) &&
if ( ( args.Contains("-p") || args.Contains(PathCommandLineArgLong) ) &&
( path == string.Empty || path[0] == "-"[0] ) )
{
var currentDirectory = Directory.GetCurrentDirectory();
Expand Down Expand Up @@ -760,7 +763,8 @@ public static bool IsSubPathOrPath(IReadOnlyList<string> args)
{
// To use only with -p or --path > current directory
if ( args.Any(arg =>
( arg.Equals("--path", StringComparison.CurrentCultureIgnoreCase) ||
( arg.Equals(PathCommandLineArgLong,
StringComparison.CurrentCultureIgnoreCase) ||
arg.Equals("-p", StringComparison.CurrentCultureIgnoreCase) )) )
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,9 @@ internal bool RemoveCorruptImage(string fileHash,
}
catch ( Exception ex )
{
const string imageCannotBeLoadedErrorMessage = "Image cannot be loaded";
var message = ex.Message;
if ( message.StartsWith("Image cannot be loaded") ) message = "Image cannot be loaded";
if ( message.StartsWith(imageCannotBeLoadedErrorMessage) ) message = imageCannotBeLoadedErrorMessage;
_logger.LogError($"[ResizeThumbnailFromThumbnailImage] Exception {fileHash} {message}", ex);
result.Success = false;
result.ErrorMessage = message;
Expand Down Expand Up @@ -382,8 +383,12 @@ internal bool RemoveCorruptImage(string fileHash,
}
catch ( Exception ex )
{
const string imageCannotBeLoadedErrorMessage = "Image cannot be loaded";
var message = ex.Message;
if ( message.StartsWith("Image cannot be loaded") ) message = "Image cannot be loaded";
if ( message.StartsWith(imageCannotBeLoadedErrorMessage) )
{
message = imageCannotBeLoadedErrorMessage;
}
_logger.LogError($"[ResizeThumbnailFromSourceImage] Exception {subPath} {message}", ex);
return (null, false, message);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { waitFor } from "@testing-library/react";
import { PageType } from "../../../../interfaces/IDetailView";
import * as FetchGet from "../../../../shared/fetch/fetch-get";
import { FileListCache } from "../../../../shared/filelist-cache";
import { RemoveCache } from "./remove-cache";

describe("RemoveCache function", () => {
beforeEach(() => {
jest.useFakeTimers();
});

afterEach(() => {
jest.clearAllTimers();
});

it("should call setIsLoading with true", () => {
const setIsLoading = jest.fn();
RemoveCache(setIsLoading, "/parent", "search", jest.fn(), jest.fn());
expect(setIsLoading).toHaveBeenCalledWith(true);
});

it("should call CacheCleanEverything", () => {
const cacheCleanEverything = jest.spyOn(FileListCache.prototype, "CacheCleanEverything");
RemoveCache(jest.fn(), "/parent", "search", jest.fn(), jest.fn());
expect(cacheCleanEverything).toHaveBeenCalled();
cacheCleanEverything.mockRestore();
});

it("should call FetchGet with the correct URL to remove cache", () => {
const mockFetchGet = jest
.spyOn(FetchGet, "default")
.mockReset()
.mockImplementationOnce(() => Promise.resolve({ statusCode: 200, data: null }));
const parentFolder = "/parent";
RemoveCache(jest.fn(), parentFolder, "search", jest.fn(), jest.fn());
expect(mockFetchGet).toHaveBeenCalledWith("/starsky/api/remove-cache?json=true&f=/parent");
expect(mockFetchGet.mock.calls[0][0]).toContain("/remove-cache");
expect(mockFetchGet.mock.calls[0][0]).toContain(
"/starsky/api/remove-cache?json=true&f=/parent"
);
mockFetchGet.mockRestore();
});

it("should call FetchGet with invalid url to remove cache", () => {
const mockFetchGet = jest
.spyOn(FetchGet, "default")
.mockReset()
.mockImplementationOnce(() => Promise.resolve({ statusCode: 200, data: null }));

const parent: string | undefined = undefined as unknown as string;

RemoveCache(jest.fn(), parent, "search", jest.fn(), jest.fn());
expect(mockFetchGet).toHaveBeenCalledWith("/starsky/api/remove-cache?json=true&f=/");
expect(mockFetchGet.mock.calls[0][0]).toContain("/remove-cache");
expect(mockFetchGet.mock.calls[0][0]).toContain("/starsky/api/remove-cache?json=true&f=/");
mockFetchGet.mockRestore();
});

it("should call FetchGet with the correct URL to index server API after setTimeout", async () => {
const mockFetchGet = jest
.spyOn(FetchGet, "default")
.mockImplementationOnce(() => Promise.resolve({ statusCode: 200, data: null }));

const parentFolder = "/parent";
const historyLocationSearch = "search";
RemoveCache(jest.fn(), parentFolder, historyLocationSearch, jest.fn(), jest.fn());

jest.runAllTimers();

expect(mockFetchGet).toHaveBeenCalledWith("/starsky/api/remove-cache?json=true&f=/parent");

mockFetchGet.mockRestore();
});

it("should dispatch force-reset action when payload has fileIndexItems", async () => {
const dispatch = jest.fn();
const propsHandleExit = jest.fn();

const mediaArchiveData = {
data: {
pageType: PageType.Archive,
fileIndexItems: [{}, {}] // Mocking fileIndexItems
},
statusCode: 200
};
const mockFetchGet = jest
.spyOn(FetchGet, "default")
.mockImplementationOnce(() => Promise.resolve(mediaArchiveData))
.mockImplementationOnce(() => Promise.resolve(mediaArchiveData));

jest.useFakeTimers();

RemoveCache(jest.fn(), "/parent", "search", dispatch, propsHandleExit);

jest.advanceTimersByTime(600);

await waitFor(() => {
expect(propsHandleExit).toHaveBeenCalled();

expect(dispatch).toHaveBeenCalledWith({
type: "force-reset",
payload: mediaArchiveData.data
});
});

mockFetchGet.mockRestore();
});

it("should not dispatch force-reset action when payload has no fileIndexItems", async () => {
const dispatch = jest.fn();
const propsHandleExit = jest.fn();

const mediaArchiveData = {
data: {
pageType: PageType.Archive
},
statusCode: 200
};
const mockFetchGet = jest
.spyOn(FetchGet, "default")
.mockImplementationOnce(() => Promise.resolve(mediaArchiveData))
.mockImplementationOnce(() => Promise.resolve(mediaArchiveData));

jest.useFakeTimers();

RemoveCache(jest.fn(), "/parent", "search", dispatch, propsHandleExit);

jest.advanceTimersByTime(600);

await waitFor(() => {
expect(propsHandleExit).toHaveBeenCalled();

expect(dispatch).toHaveBeenCalledTimes(0);
});

mockFetchGet.mockRestore();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Dispatch, SetStateAction } from "react";
import { ArchiveAction } from "../../../../contexts/archive-context.tsx";
import { IArchiveProps } from "../../../../interfaces/IArchiveProps.ts";
import { CastToInterface } from "../../../../shared/cast-to-interface.ts";
import FetchGet from "../../../../shared/fetch/fetch-get.ts";
import { FileListCache } from "../../../../shared/filelist-cache.ts";
import { URLPath } from "../../../../shared/url/url-path.ts";
import { UrlQuery } from "../../../../shared/url/url-query.ts";

/**
* Remove Folder cache
*/
export function RemoveCache(
setIsLoading: Dispatch<SetStateAction<boolean>>,
propsParentFolder: string,
historyLocationSearch: string,
dispatch: Dispatch<ArchiveAction>,
propsHandleExit: () => void
) {
setIsLoading(true);
new FileListCache().CacheCleanEverything();
const parentFolder = propsParentFolder ?? "/";
FetchGet(new UrlQuery().UrlRemoveCache(new URLPath().encodeURI(parentFolder)))
.then(() => {
return new Promise<string>((resolve) => {
setTimeout(() => {
resolve(
new UrlQuery().UrlIndexServerApi(new URLPath().StringToIUrl(historyLocationSearch))
);
}, 600);
});
})
.then((url: string) => {
return FetchGet(url, { "Cache-Control": "no-store, max-age=0" });
})
.then((connectionResult) => {
const removeCacheResult = new CastToInterface().MediaArchive(connectionResult.data);
const payload = removeCacheResult.data as IArchiveProps;
if (payload.fileIndexItems) {
dispatch({ type: "force-reset", payload });
}
propsHandleExit();
})
.catch((error) => {
console.error("Error:", error);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@ import { ArchiveContext } from "../../../contexts/archive-context";
import useGlobalSettings from "../../../hooks/use-global-settings";
import useInterval from "../../../hooks/use-interval";
import useLocation from "../../../hooks/use-location/use-location";
import { IArchiveProps } from "../../../interfaces/IArchiveProps";
import localization from "../../../localization/localization.json";
import { CastToInterface } from "../../../shared/cast-to-interface";
import FetchGet from "../../../shared/fetch/fetch-get";
import FetchPost from "../../../shared/fetch/fetch-post";
import { FileListCache } from "../../../shared/filelist-cache";
import { Language } from "../../../shared/language";
import { URLPath } from "../../../shared/url/url-path";
import { UrlQuery } from "../../../shared/url/url-query";
import Modal from "../../atoms/modal/modal";
import Preloader from "../../atoms/preloader/preloader";
import ForceSyncWaitButton from "../../molecules/force-sync-wait-button/force-sync-wait-button";
import { RemoveCache } from "./internal/remove-cache.ts";

interface IModalDisplayOptionsProps {
isOpen: boolean;
handleExit: Function;
handleExit: () => void;
parentFolder?: string;
}

Expand Down Expand Up @@ -53,30 +51,6 @@ const ModalArchiveSynchronizeManually: React.FunctionComponent<IModalDisplayOpti
setCollections(new URLPath().StringToIUrl(history.location.search).collections !== false);
}, [collections, history.location.search]);

/**
* Remove Folder cache
*/
function removeCache() {
setIsLoading(true);
new FileListCache().CacheCleanEverything();
const parentFolder = props.parentFolder ?? "/";
FetchGet(new UrlQuery().UrlRemoveCache(new URLPath().encodeURI(parentFolder))).then(() => {
setTimeout(() => {
const url = new UrlQuery().UrlIndexServerApi(
new URLPath().StringToIUrl(history.location.search)
);
FetchGet(url, { "Cache-Control": "no-store, max-age=0" }).then((connectionResult) => {
const removeCacheResult = new CastToInterface().MediaArchive(connectionResult.data);
const payload = removeCacheResult.data as IArchiveProps;
if (payload.fileIndexItems) {
dispatch({ type: "force-reset", payload });
}
props.handleExit();
});
}, 600);
});
}

const [geoSyncPercentage, setGeoSyncPercentage] = useState(0);

function geoSync() {
Expand Down Expand Up @@ -139,7 +113,19 @@ const ModalArchiveSynchronizeManually: React.FunctionComponent<IModalDisplayOpti
callback={() => props.handleExit()}
dispatch={dispatch}
></ForceSyncWaitButton>
<button className="btn btn--default" data-test="remove-cache" onClick={() => removeCache()}>
<button
className="btn btn--default"
data-test="remove-cache"
onClick={() =>
RemoveCache(
setIsLoading,
props.parentFolder ?? "",
history.location.search,
dispatch,
props.handleExit
)
}
>
{MessageRemoveCache}
</button>
<button
Expand Down

1 comment on commit 2ba54b6

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.