firstsun-dev_git-files-sync/tests/logic/sync-manager-mapping.test.ts
ClaudiaFang 72ed2cde75 feat: add Simplified Chinese locale, settings what's-new banner, and 1.3.0 changelog
- src/i18n: add zh-cn locale, explicit language override setting
  (LanguageSetting), and moment-locale -> zh-cn/zh-tw resolution.
- src/settings.ts: persistent banner at the top of the settings tab
  showing the current version's notable changelog highlights, so users
  who dismiss or miss the WhatsNewModal can still find them. Dismissal
  is tracked separately (bannerDismissedVersion) from the modal's
  once-per-upgrade lastSeenVersion gate.
- src/changelog.ts: curate the 1.3.0 release notes (multi-language UI,
  faster status refresh, symlink-pull fix, ignore-sync setting,
  connection status display, resizable conflict modal, folder picker,
  clearer connection errors, this what's-new tip).

Part of #39.
2026-07-14 13:12:14 +00:00

127 lines
3.9 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { SyncManager } from '../../src/logic/sync-manager';
import { App, TFile } from 'obsidian';
import type { GitServiceInterface } from '../../src/services/git-service-interface';
import type { GitLabFilesPushSettings } from '../../src/settings';
vi.mock('obsidian', () => ({
Notice: vi.fn(),
TFile: class {
path: string = '';
name: string = '';
},
App: class {},
}));
const mockApp = {
vault: {
read: vi.fn(),
modify: vi.fn(),
getFileByPath: vi.fn(),
getAbstractFileByPath: vi.fn(),
createFolder: vi.fn(),
adapter: {
exists: vi.fn(),
read: vi.fn(),
write: vi.fn(),
}
}
} as unknown as App;
const mockGetFile = vi.fn();
const mockPushFile = vi.fn();
const mockGitService = {
getFile: mockGetFile,
pushFile: mockPushFile,
} as unknown as GitServiceInterface;
const mockSettings: GitLabFilesPushSettings = {
serviceType: 'gitlab',
gitlabToken: '',
gitlabBaseUrl: 'https://gitlab.com',
projectId: '',
githubToken: '',
githubOwner: '',
githubRepo: '',
giteaToken: '',
giteaBaseUrl: '',
giteaOwner: '',
giteaRepo: '',
branch: 'main',
rootPath: 'notes',
vaultFolder: 'Work',
syncMetadata: {},
symlinkHandling: 'real',
ignorePatterns: '',
lastSeenVersion: '',
bannerDismissedVersion: '',
language: 'system',
};
describe('SyncManager Mapping', () => {
let manager: SyncManager;
beforeEach(() => {
vi.clearAllMocks();
mockSettings.syncMetadata = {};
manager = new SyncManager(mockApp, mockGitService, mockSettings);
});
it('should strip vaultFolder when pushing', async () => {
const vaultPath = 'Work/test.md';
const mockFile = Object.assign(new TFile(), { path: vaultPath, name: 'test.md' });
const getFileByPathSpy = vi.spyOn(mockApp.vault, 'getFileByPath');
const readSpy = vi.spyOn(mockApp.vault, 'read');
getFileByPathSpy.mockReturnValue(mockFile);
readSpy.mockResolvedValue('content');
vi.mocked(mockGetFile).mockResolvedValue({ content: '', sha: '' });
vi.mocked(mockPushFile).mockResolvedValue({ path: 'notes/test.md' });
await manager.pushFile(mockFile);
expect(mockGetFile).toHaveBeenCalledWith('test.md', 'main');
expect(mockPushFile).toHaveBeenCalledWith(
'test.md',
'content',
'main',
'Update test.md from Obsidian',
''
);
});
it('should map back to vaultFolder when pulling', async () => {
const vaultPath = 'Work/remote.md';
vi.mocked(mockGetFile).mockResolvedValue({ content: 'remote content', sha: 'sha' });
const existsSpy = vi.spyOn(mockApp.vault.adapter, 'exists');
const writeSpy = vi.spyOn(mockApp.vault.adapter, 'write');
existsSpy.mockResolvedValue(false);
writeSpy.mockResolvedValue(undefined);
await manager.pullFile(vaultPath);
expect(mockGetFile).toHaveBeenCalledWith('remote.md', 'main');
expect(writeSpy).toHaveBeenCalledWith(vaultPath, 'remote content');
});
it('should handle root-level files correctly when no vaultFolder', async () => {
mockSettings.vaultFolder = '';
manager = new SyncManager(mockApp, mockGitService, mockSettings);
const path = 'root.md';
const mockFile = Object.assign(new TFile(), { path, name: 'root.md' });
const getFileByPathSpy = vi.spyOn(mockApp.vault, 'getFileByPath');
const readSpy = vi.spyOn(mockApp.vault, 'read');
getFileByPathSpy.mockReturnValue(mockFile);
readSpy.mockResolvedValue('content');
vi.mocked(mockGetFile).mockResolvedValue({ content: '', sha: '' });
await manager.pushFile(mockFile);
expect(mockGetFile).toHaveBeenCalledWith('root.md', 'main');
});
});