-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1715 from qdraw/feature/202409_rotate_change
implement rotation change
- Loading branch information
Showing
10 changed files
with
447 additions
and
347 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...rc/components/molecules/menu-option-rotate-image-90/internal/request-new-filehash.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { IDetailView } from "../../../../interfaces/IDetailView"; | ||
import { IFileIndexItem, Orientation } from "../../../../interfaces/IFileIndexItem"; | ||
import * as FetchGet from "../../../../shared/fetch/fetch-get.ts"; // for expect assertions | ||
import { RequestNewFileHash } from "./request-new-filehash.ts"; | ||
|
||
describe("requestNewFileHash", () => { | ||
const mockState: IDetailView = { | ||
subPath: "/path/to/image.jpg", | ||
fileIndexItem: { | ||
fileHash: "abc123", | ||
filePath: "/path/to/image.jpg", | ||
orientation: Orientation.Horizontal | ||
} as unknown as IFileIndexItem | ||
} as unknown as IDetailView; | ||
|
||
const mockSetIsLoading = jest.fn(); | ||
const mockDispatch = jest.fn(); | ||
|
||
let fetchGetSpy: jest.SpyInstance; | ||
|
||
beforeEach(() => { | ||
fetchGetSpy = jest.spyOn(FetchGet, "default"); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("returns null if FetchGet fails", async () => { | ||
fetchGetSpy.mockResolvedValueOnce(null); | ||
|
||
const result = await RequestNewFileHash(mockState, mockSetIsLoading, mockDispatch); | ||
|
||
expect(result).toBeNull(); | ||
expect(mockSetIsLoading).toHaveBeenCalledTimes(0); | ||
}); | ||
|
||
it("returns null if FetchGet status code is not 200", async () => { | ||
const mockResult = { | ||
statusCode: 404 // or any non-200 status code | ||
}; | ||
fetchGetSpy.mockResolvedValueOnce(mockResult); | ||
|
||
const result = await RequestNewFileHash(mockState, mockSetIsLoading, mockDispatch); | ||
|
||
expect(result).toBeNull(); | ||
expect(mockSetIsLoading).toHaveBeenCalledWith(false); | ||
}); | ||
|
||
it("updates context and returns true when fileHash changes", async () => { | ||
const mockResult = { | ||
statusCode: 200, | ||
data: { | ||
fileIndexItem: { | ||
fileHash: "test" | ||
}, | ||
pageType: "DetailView" | ||
} | ||
}; | ||
fetchGetSpy.mockResolvedValueOnce(mockResult); | ||
|
||
const result = await RequestNewFileHash(mockState, mockSetIsLoading, mockDispatch); | ||
|
||
expect(result).toBe(true); | ||
expect(mockDispatch).toHaveBeenCalledWith({ | ||
fileHash: "test", | ||
filePath: undefined, | ||
orientation: "Horizontal", | ||
type: "update" | ||
}); | ||
expect(mockSetIsLoading).toHaveBeenCalledWith(false); | ||
}); | ||
|
||
it("returns false and updates context when fileHash remains the same", async () => { | ||
const mockResult = { | ||
statusCode: 200, | ||
data: { | ||
fileIndexItem: { | ||
fileHash: "abc123" // same as mockState.fileIndexItem.fileHash | ||
}, | ||
pageType: "DetailView" | ||
} | ||
}; | ||
fetchGetSpy.mockResolvedValueOnce(mockResult); | ||
|
||
const result = await RequestNewFileHash(mockState, mockSetIsLoading, mockDispatch); | ||
|
||
expect(result).toBe(false); | ||
expect(mockDispatch).toHaveBeenCalledTimes(0); | ||
expect(mockSetIsLoading).toHaveBeenCalledTimes(0); | ||
}); | ||
}); |
41 changes: 41 additions & 0 deletions
41
...app/src/components/molecules/menu-option-rotate-image-90/internal/request-new-filehash.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { Dispatch } from "react"; | ||
import { DetailViewAction } from "../../../../contexts/detailview-context.tsx"; | ||
import { IDetailView } from "../../../../interfaces/IDetailView.ts"; | ||
import { Orientation } from "../../../../interfaces/IFileIndexItem.ts"; | ||
import { CastToInterface } from "../../../../shared/cast-to-interface.ts"; | ||
import FetchGet from "../../../../shared/fetch/fetch-get.ts"; | ||
import { UrlQuery } from "../../../../shared/url/url-query.ts"; | ||
|
||
/** | ||
* Checks if the hash is changes and update Context: orientation + fileHash | ||
*/ | ||
|
||
export async function RequestNewFileHash( | ||
state: IDetailView, | ||
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>, | ||
dispatch: Dispatch<DetailViewAction> | ||
): Promise<boolean | null> { | ||
const resultGet = await FetchGet(new UrlQuery().UrlIndexServerApi({ f: state.subPath })); | ||
if (!resultGet) return null; | ||
if (resultGet.statusCode !== 200) { | ||
console.error(resultGet); | ||
setIsLoading(false); | ||
return null; | ||
} | ||
const media = new CastToInterface().MediaDetailView(resultGet.data).data; | ||
const orientation = media?.fileIndexItem?.orientation | ||
? media.fileIndexItem.orientation | ||
: Orientation.Horizontal; | ||
|
||
// the hash changes if you rotate an image | ||
if (media.fileIndexItem.fileHash === state.fileIndexItem.fileHash) return false; | ||
|
||
dispatch({ | ||
type: "update", | ||
orientation, | ||
fileHash: media.fileIndexItem.fileHash, | ||
filePath: media.fileIndexItem.filePath | ||
}); | ||
setIsLoading(false); | ||
return true; | ||
} |
78 changes: 78 additions & 0 deletions
78
...ponents/molecules/menu-option-rotate-image-90/internal/trigger-file-hash-request.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { act } from "react"; | ||
import { IDetailView } from "../../../../interfaces/IDetailView"; | ||
import { Orientation } from "../../../../interfaces/IFileIndexItem"; | ||
import * as RequestNewFileHash from "./request-new-filehash"; | ||
import { TriggerFileHashRequest } from "./trigger-file-hash-request"; | ||
|
||
describe("TriggerFileHashRequest", () => { | ||
const state: IDetailView = { | ||
subPath: "/test/image.jpg", | ||
fileIndexItem: { | ||
fileHash: "123", | ||
filePath: "/test/image.jpg", | ||
orientation: Orientation.Horizontal | ||
} | ||
} as IDetailView; | ||
|
||
beforeEach(() => { | ||
jest.useFakeTimers(); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.useRealTimers(); | ||
}); | ||
|
||
it("returns immediately when the file hash changes on the first attempt", () => { | ||
const requestSpy = jest | ||
.spyOn(RequestNewFileHash, "RequestNewFileHash") | ||
.mockResolvedValueOnce(true); | ||
|
||
const setIsLoading = jest.fn(); | ||
TriggerFileHashRequest(state, setIsLoading, jest.fn(), 1, 1); | ||
|
||
act(() => { | ||
jest.advanceTimersByTime(100); | ||
}); | ||
|
||
jest.advanceTimersByTime(1); | ||
jest.runAllTimers(); | ||
expect(requestSpy).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("retry when failed", () => { | ||
const requestSpy = jest | ||
.spyOn(RequestNewFileHash, "RequestNewFileHash") | ||
.mockResolvedValueOnce(false); | ||
|
||
const setIsLoading = jest.fn(); | ||
TriggerFileHashRequest(state, setIsLoading, jest.fn(), 1, 1); | ||
|
||
act(() => { | ||
jest.advanceTimersByTime(100); | ||
}); | ||
|
||
jest.advanceTimersByTime(1); | ||
jest.runAllTimers(); | ||
expect(requestSpy).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
it("retry when failed (max 3 times)", () => { | ||
const requestSpy = jest | ||
.spyOn(RequestNewFileHash, "RequestNewFileHash") | ||
.mockResolvedValueOnce(false) | ||
.mockResolvedValueOnce(false) | ||
.mockResolvedValueOnce(false) | ||
.mockResolvedValueOnce(false); | ||
|
||
const setIsLoading = jest.fn(); | ||
TriggerFileHashRequest(state, setIsLoading, jest.fn(), 1, 1); | ||
|
||
act(() => { | ||
jest.advanceTimersByTime(100); | ||
}); | ||
|
||
jest.advanceTimersByTime(1); | ||
jest.runAllTimers(); | ||
expect(requestSpy).toHaveBeenCalledTimes(3); | ||
}); | ||
}); |
28 changes: 28 additions & 0 deletions
28
...c/components/molecules/menu-option-rotate-image-90/internal/trigger-file-hash-request.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Dispatch } from "react"; | ||
import { DetailViewAction } from "../../../../contexts/detailview-context"; | ||
import { IDetailView } from "../../../../interfaces/IDetailView"; | ||
import { RequestNewFileHash } from "./request-new-filehash"; | ||
|
||
export function TriggerFileHashRequest( | ||
state: IDetailView, | ||
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>, | ||
dispatch: Dispatch<DetailViewAction>, | ||
retry: number = 0, | ||
delay: number = 3000 | ||
) { | ||
const maxRetries = 3; | ||
|
||
const attemptRequest = (currentRetry: number) => { | ||
setTimeout(() => { | ||
RequestNewFileHash(state, setIsLoading, dispatch).then((result) => { | ||
if (result === false && currentRetry < maxRetries) { | ||
attemptRequest(currentRetry + 1); | ||
} else { | ||
setIsLoading(false); | ||
} | ||
}); | ||
}, delay); | ||
}; | ||
|
||
return attemptRequest(retry); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
fc3036f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Published on https://starskyapp.netlify.app as production
🚀 Deployed on https://670ff6947d547cc79d40752b--starskyapp.netlify.app