fix: regresi hapus folder tidak kosong, tambah test contentEditor
- Perbaiki pemanggilan deleteEntry di +page.svelte baris 531: argumen force=true tidak lagi diteruskan dengan benar setelah signature fungsi berubah (confirmCritical ditambah di tengah) - Koreksi komentar dengan karakter Mandarin di content_editor.py baris 488 - Tambah test unit contentEditor.test.ts dengan 5 kasus: - deleteEntry force delete - deleteEntry confirm_critical untuk file kritis - deleteEntry default parameter - renameEntry standar - renameEntry confirm_critical Fixes: hapus folder dengan isi tidak lagi gagal 409. All tests: 119 passed.
This commit is contained in:
parent
1659063784
commit
f78eaaca11
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { deleteEntry, renameEntry } from './contentEditor';
|
||||||
|
|
||||||
|
describe('deleteEntry', () => {
|
||||||
|
it('mengirim force=true saat dipanggil dengan argumen force', async () => {
|
||||||
|
const fetchMock = vi.fn().mockResolvedValue({ json: async () => ({ success: true }) });
|
||||||
|
global.fetch = fetchMock;
|
||||||
|
|
||||||
|
await deleteEntry('content', 'folder_x', false, true);
|
||||||
|
|
||||||
|
const url = fetchMock.mock.calls[0][0] as string;
|
||||||
|
expect(url).toContain('force=true');
|
||||||
|
expect(url).toContain('confirm_critical=false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mengirim confirm_critical=true untuk file navigasi kritis', async () => {
|
||||||
|
const fetchMock = vi.fn().mockResolvedValue({ json: async () => ({ success: true }) });
|
||||||
|
global.fetch = fetchMock;
|
||||||
|
|
||||||
|
await deleteEntry('content', 'home.md', true);
|
||||||
|
|
||||||
|
const url = fetchMock.mock.calls[0][0] as string;
|
||||||
|
expect(url).toContain('confirm_critical=true');
|
||||||
|
expect(url).toContain('force=false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mengirim query string yang benar untuk folder biasa', async () => {
|
||||||
|
const fetchMock = vi.fn().mockResolvedValue({ json: async () => ({ success: true }) });
|
||||||
|
global.fetch = fetchMock;
|
||||||
|
|
||||||
|
await deleteEntry('content', 'some_folder');
|
||||||
|
|
||||||
|
const url = fetchMock.mock.calls[0][0] as string;
|
||||||
|
expect(url).toContain('force=false');
|
||||||
|
expect(url).toContain('confirm_critical=false');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('renameEntry', () => {
|
||||||
|
it('mengirim rename dengan argumen standar', async () => {
|
||||||
|
const fetchMock = vi.fn().mockResolvedValue({ json: async () => ({ success: true }) });
|
||||||
|
global.fetch = fetchMock;
|
||||||
|
|
||||||
|
await renameEntry('content', 'old.md', 'new.md', false);
|
||||||
|
|
||||||
|
expect(fetchMock.mock.calls[0][1]).toMatchObject({
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mengirim confirm_critical=true untuk filename kritis', async () => {
|
||||||
|
const fetchMock = vi.fn().mockResolvedValue({ json: async () => ({ success: true }) });
|
||||||
|
global.fetch = fetchMock;
|
||||||
|
|
||||||
|
await renameEntry('content', 'home.md', 'renamed.md', true);
|
||||||
|
|
||||||
|
const body = JSON.parse(fetchMock.mock.calls[0][1]?.body ?? '{}');
|
||||||
|
expect(body.confirm_critical).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -528,7 +528,7 @@
|
||||||
}
|
}
|
||||||
} else if (res.needs_force) {
|
} else if (res.needs_force) {
|
||||||
if (window.confirm(`Folder "${name}" tidak kosong. Hapus semua isi?`)) {
|
if (window.confirm(`Folder "${name}" tidak kosong. Hapus semua isi?`)) {
|
||||||
const forceRes = await deleteEntry(mgr.treeRoot, path, true);
|
const forceRes = await deleteEntry(mgr.treeRoot, path, PROTECTED_BASENAMES.has(name), true);
|
||||||
if (forceRes.success) {
|
if (forceRes.success) {
|
||||||
await loadTrees();
|
await loadTrees();
|
||||||
if (mgr.activePath === path) {
|
if (mgr.activePath === path) {
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ def upload_asset():
|
||||||
|
|
||||||
# Validasi isi benar-benar gambar (bukan cuma cek ekstensi) — SVG
|
# Validasi isi benar-benar gambar (bukan cuma cek ekstensi) — SVG
|
||||||
# dikecualikan (Pillow tidak parse SVG).
|
# dikecualikan (Pillow tidak parse SVG).
|
||||||
# Pakai .load() (decode sungguhan)而不是 .verify(): .verify() melakukan
|
# Pakai .load() (decode sungguhan) bukan .verify(): .verify() melakukan
|
||||||
# CRC check strict pada IDAT yang sering FALSE-POSITIVE pada PNG valid
|
# CRC check strict pada IDAT yang sering FALSE-POSITIVE pada PNG valid
|
||||||
# (terutama PNG sederhana / hasil re-encode) → backend 500. .load()
|
# (terutama PNG sederhana / hasil re-encode) → backend 500. .load()
|
||||||
# sudah cukup membuktikan file adalah gambar yang bisa di-decode.
|
# sudah cukup membuktikan file adalah gambar yang bisa di-decode.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue