chore: merge origin/main with local test additions
All checks were successful
CI / verify (push) Successful in 10m1s
All checks were successful
CI / verify (push) Successful in 10m1s
Resolves conflict in repo.spec.ts by combining getRepoPermission tests from main with the getFiles and queryFileContent tests from the local test pass. Adds getRepoPermission to the userRepo.store spec mocks so the new permission probe added upstream doesn't break the store tests.
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
const { reposGet } = vi.hoisted(() => ({ reposGet: vi.fn() }))
|
||||
|
||||
vi.mock("./octo", () => ({
|
||||
getOctokit: vi.fn(),
|
||||
getOctokit: vi.fn().mockResolvedValue({
|
||||
repos: { get: reposGet }
|
||||
}),
|
||||
runWithAuthRetry: vi.fn()
|
||||
}))
|
||||
|
||||
@@ -18,12 +22,52 @@ vi.mock("@/modules/note/cache/prepareNoteCache", () => ({
|
||||
}))
|
||||
|
||||
import { getOctokit, runWithAuthRetry } from "./octo"
|
||||
import { getFiles, queryFileContent } from "./repo"
|
||||
import {
|
||||
getFiles,
|
||||
getRepoPermission,
|
||||
queryFileContent
|
||||
} from "./repo"
|
||||
|
||||
const makeOctokitWithRequest = (impl: (route: string, params: unknown) => unknown) => ({
|
||||
request: vi.fn(impl)
|
||||
})
|
||||
|
||||
describe("getRepoPermission", () => {
|
||||
beforeEach(() => {
|
||||
reposGet.mockReset()
|
||||
vi.mocked(getOctokit).mockResolvedValue({
|
||||
repos: { get: reposGet }
|
||||
} as never)
|
||||
})
|
||||
|
||||
it("returns true when permissions.push is true", async () => {
|
||||
reposGet.mockResolvedValue({
|
||||
data: { permissions: { push: true } }
|
||||
})
|
||||
await expect(getRepoPermission("owner", "repo")).resolves.toBe(true)
|
||||
})
|
||||
|
||||
it("returns false when permissions.push is false", async () => {
|
||||
reposGet.mockResolvedValue({
|
||||
data: { permissions: { push: false } }
|
||||
})
|
||||
await expect(getRepoPermission("owner", "repo")).resolves.toBe(false)
|
||||
})
|
||||
|
||||
it("returns false when permissions is missing (anonymous request)", async () => {
|
||||
reposGet.mockResolvedValue({
|
||||
data: {}
|
||||
})
|
||||
await expect(getRepoPermission("owner", "repo")).resolves.toBe(false)
|
||||
})
|
||||
|
||||
it("returns false when owner or repo is empty", async () => {
|
||||
await expect(getRepoPermission("", "repo")).resolves.toBe(false)
|
||||
await expect(getRepoPermission("owner", "")).resolves.toBe(false)
|
||||
expect(reposGet).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe("getFiles", () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(getOctokit).mockReset()
|
||||
|
||||
@@ -4,6 +4,18 @@ import { RepoFile } from "@/modules/repo/interfaces/RepoFile"
|
||||
import { UserSettings } from "@/modules/repo/interfaces/UserSettings"
|
||||
import { getOctokit, runWithAuthRetry } from "@/modules/repo/services/octo"
|
||||
|
||||
export const getRepoPermission = async (
|
||||
owner: string,
|
||||
repo: string
|
||||
): Promise<boolean> => {
|
||||
if (!owner || !repo) {
|
||||
return false
|
||||
}
|
||||
const octokit = await getOctokit()
|
||||
const { data } = await octokit.repos.get({ owner, repo })
|
||||
return data.permissions?.push ?? false
|
||||
}
|
||||
|
||||
export const getFiles = async (
|
||||
owner: string,
|
||||
repo: string
|
||||
|
||||
@@ -14,7 +14,8 @@ vi.mock("@/modules/repo/services/repo", () => ({
|
||||
getFiles: vi.fn().mockResolvedValue([]),
|
||||
getMainReadme: vi.fn().mockResolvedValue(null),
|
||||
getCachedMainReadme: vi.fn().mockResolvedValue(null),
|
||||
getUserSettingsContent: vi.fn().mockResolvedValue(null)
|
||||
getUserSettingsContent: vi.fn().mockResolvedValue(null),
|
||||
getRepoPermission: vi.fn().mockResolvedValue(false)
|
||||
}))
|
||||
|
||||
vi.mock("@/modules/user/service/signIn", () => ({
|
||||
@@ -26,6 +27,7 @@ import {
|
||||
getCachedMainReadme,
|
||||
getFiles,
|
||||
getMainReadme,
|
||||
getRepoPermission,
|
||||
getUserSettingsContent
|
||||
} from "@/modules/repo/services/repo"
|
||||
|
||||
@@ -145,6 +147,7 @@ describe("userRepo store — setUserRepo", () => {
|
||||
vi.mocked(getMainReadme).mockResolvedValue(null)
|
||||
vi.mocked(getCachedMainReadme).mockResolvedValue(null)
|
||||
vi.mocked(getUserSettingsContent).mockResolvedValue(null)
|
||||
vi.mocked(getRepoPermission).mockResolvedValue(false)
|
||||
})
|
||||
|
||||
it("sets user and repo immediately and clears loadError", async () => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
getCachedMainReadme,
|
||||
getFiles,
|
||||
getMainReadme,
|
||||
getRepoPermission,
|
||||
getUserSettingsContent
|
||||
} from "@/modules/repo/services/repo"
|
||||
import { refreshToken } from "@/modules/user/service/signIn"
|
||||
@@ -24,6 +25,7 @@ interface State {
|
||||
userSettings?: UserSettings | null
|
||||
needToLogin: boolean
|
||||
loadError: RepoLoadError
|
||||
canPush: boolean
|
||||
_requestId: number
|
||||
}
|
||||
|
||||
@@ -46,6 +48,7 @@ export const useUserRepoStore = defineStore("USER_REPO_STATE", {
|
||||
userSettings: undefined,
|
||||
needToLogin: false,
|
||||
loadError: null,
|
||||
canPush: false,
|
||||
_requestId: 0
|
||||
}),
|
||||
actions: {
|
||||
@@ -78,6 +81,7 @@ export const useUserRepoStore = defineStore("USER_REPO_STATE", {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.loadError = null
|
||||
this.canPush = false
|
||||
|
||||
let lsLayout: Partial<UserSettings> = {}
|
||||
try {
|
||||
@@ -120,6 +124,17 @@ export const useUserRepoStore = defineStore("USER_REPO_STATE", {
|
||||
|
||||
if (requestId !== this._requestId) return
|
||||
|
||||
getRepoPermission(user, repo)
|
||||
.then((canPush) => {
|
||||
if (requestId !== this._requestId) return
|
||||
this.canPush = canPush
|
||||
})
|
||||
.catch((error) => {
|
||||
if (requestId !== this._requestId) return
|
||||
console.warn("getRepoPermission failed", error)
|
||||
this.canPush = false
|
||||
})
|
||||
|
||||
getFiles(user, repo)
|
||||
.then(async (files) => {
|
||||
if (requestId !== this._requestId) return
|
||||
@@ -230,6 +245,28 @@ export const useUserRepoStore = defineStore("USER_REPO_STATE", {
|
||||
})
|
||||
this.files = newFiles
|
||||
},
|
||||
registerUploadedFile(file: RepoFile) {
|
||||
if (!file.path) {
|
||||
return
|
||||
}
|
||||
|
||||
const savedRepoId = generateId(
|
||||
DataType.SavedRepo,
|
||||
`${this.user}-${this.repo}`
|
||||
)
|
||||
const newFiles = [
|
||||
...toRaw(this.files).filter((f) => f.path !== file.path),
|
||||
toRaw(file)
|
||||
]
|
||||
data.update<DataType.SavedRepo, SavedRepo>({
|
||||
_id: savedRepoId,
|
||||
$type: DataType.SavedRepo,
|
||||
repo: this.repo,
|
||||
user: this.user,
|
||||
files: newFiles
|
||||
})
|
||||
this.files = newFiles
|
||||
},
|
||||
resetUserRepo() {
|
||||
this.user = ""
|
||||
this.repo = ""
|
||||
@@ -239,6 +276,7 @@ export const useUserRepoStore = defineStore("USER_REPO_STATE", {
|
||||
resetFiles() {
|
||||
this.files = []
|
||||
this.readme = null
|
||||
this.canPush = false
|
||||
},
|
||||
setFontFamily(fontFamily: string) {
|
||||
if (!this.userSettings) {
|
||||
|
||||
7
src/modules/user/service/oauthReturnPath.ts
Normal file
7
src/modules/user/service/oauthReturnPath.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const GITHUB_OAUTH_RETURN_PATH_KEY = "github-oauth-return-path"
|
||||
|
||||
export const consumeGithubOAuthReturnPath = (): string | null => {
|
||||
const path = sessionStorage.getItem(GITHUB_OAUTH_RETURN_PATH_KEY)
|
||||
sessionStorage.removeItem(GITHUB_OAUTH_RETURN_PATH_KEY)
|
||||
return path
|
||||
}
|
||||
Reference in New Issue
Block a user