TidGi-Desktop/features/subWiki.feature
lin onetwo 7edb132d32
Fix/watch fs and ai commit (#674)
* fix: missing return

* feat: showApiKey

* feat: undo commit

* feat: amend commit

* fix: file name quoted in git log

* fix: wikiWorkspaceDefaultValues

* fix: no ai commit message sometimes

* Persist only non-default preferences to storage

Added a utility to store only preferences that differ from defaults, reducing storage size and improving config readability. Updated the setPreferences method to use this utility before saving preferences.

* fix: External Attachment Handling in fs plugin instead of ext-attachment-plugin to handle direct tag update case which won't trigger  th-saving-tiddler hook

* feat: api for plugin to create base64 file

* Show all untracked files and recreate Git history window

Updated git status commands to use '-uall' for displaying all untracked files, not just directories. Modified windowService.open calls for Git history to include the { recreate: true } option, ensuring the window is refreshed when opened from various menus.

* fix: handling of external attachments with _canonical_uri

Ensure tiddlers with _canonical_uri are always saved as .tid files, not as binary files, by forcing the .tid extension in FileSystemAdaptor. Update tests to verify this behavior. Also, skip loading files from the external attachments folder in loadWikiTiddlersWithSubWikis to prevent them from being loaded as separate tiddlers.

* Refactor external attachment utilities to module exports

Refactored externalAttachmentUtilities to use ES module exports instead of attaching functions to $tw.utils. Updated imports and mocks accordingly, removed related type definitions from ExtendedUtilities, and cleaned up obsolete meta file.

* disable enableFileSystemWatch to prevent bug for innocent users

* fix: test that requires enableFileSystemWatch use new step set to true

* Fix extension filter usage and sync workspace state after save

Refactored variable naming for extension filters in FileSystemAdaptor to improve clarity and fixed their usage in generateTiddlerFileInfo calls. Removed an unused import in routingUtilities.type.ts. Added a useEffect in useForm to sync workspace state with originalWorkspace after save, ensuring the save button disappears as expected.

* fix: review

* lint

* feat: unify AI commit entry points and add availability check  - Unified all AI commit message generation to use syncService.syncWikiIfNeeded() for consistent business logic handling - Added externalAPI.isAIAvailable() method to check if AI provider and model are properly configured - Updated gitService.isAIGenerateBackupTitleEnabled() to use the new availability check - Removed redundant logging code since generateFromAI() automatically logs to database when externalAPIDebug is enabled - Simplified menu item creation logic in menuItems.ts - Ensured AI menu options only appear when both API credentials and free model are configured - Updated documentation to reflect the unified architecture

* Improve AI commit message diff filtering and API checks

Renamed the AI commit message entry points doc for clarity. Enhanced the AI availability check to better handle provider API key requirements, including support for providers that do not require keys. Improved plugin diff filtering to retain small config file diffs while omitting large plugin file contents, optimizing AI token usage.

* Update wiki

* Refactor and enhance Tidgi mini window initialization and sync

Refactors Tidgi mini window startup to use a new initializeTidgiMiniWindow method, improving workspace selection logic and view management. Adds concurrency locks to prevent race conditions during open/close operations. Enhances workspace sync/fixed mode handling, view cleanup, and error logging. Updates interfaces and utilities to support new behaviors and improves robustness of tray icon creation and view realignment.

* Refactor file system sync to use $tw.syncer.syncFromServer()

Introduces FileSystemWatcher to monitor file changes and collect updates for the syncer, replacing direct wiki updates in WatchFileSystemAdaptor. Updates documentation to describe the new syncer-driven architecture, echo prevention, and event handling. WatchFileSystemAdaptor now delegates file change detection and lazy loading to FileSystemWatcher, improving batch change handling and eliminating echo loops.

* Improve logging and cleanup in file system watcher and git ops

Added detailed logging to WatchFileSystemAdaptor and FileSystemWatcher for better traceability during initialization and test stabilization. Introduced a constant for the temporary git index prefix in gitOperations. Removed the unused comparison.ts utility for tiddler comparison. Enhanced comments and logging for AI commit message generation context.

* Improve GitLog i18n test and config refresh logic

Updated gitLog.feature to use only Chinese selectors for actions, revert, and discard buttons, improving i18n test reliability. In FileSystemWatcher, re-fetch workspace config before checking enableFileSystemWatch to ensure latest settings are respected. In useGitLogData, prevent file-change events from overriding commit/undo events to maintain correct auto-selection behavior.

* Improve Git log selection and test stability

Refines auto-selection logic in the Git log window to better handle uncommitted changes, commits, reverts, and undos. Updates the feature test to explicitly verify selection and UI state after each operation, improving reliability. Removes unnecessary config re-fetch in FileSystemWatcher and enhances logging for more accurate DOM update detection.

* Implement workspace config sync via tidgi.config.json

Adds support for syncing workspace configuration to tidgi.config.json in the wiki folder, enabling settings persistence and migration across devices. Introduces new documentation, feature tests, and supporting utilities for config file reading, writing, migration, and validation. Updates step definitions and test helpers to support config sync scenarios, and refactors database config utilities for modularity.

* Improve workspace config handling and sync logic

Enhances workspace lookup in step definitions to check both settings.json and tidgi.config.json, ensuring properties are found even if moved. Updates tidgiConfig write logic to remove the config file if all values are default. Refactors workspace save logic to always write syncable config to tidgi.config.json for all wiki workspaces before removing those fields from settings.json, preventing config loss.

* Update .gitignore

* Update wiki.ts

* Add delay before waiting for git log render after revert

- Add 1 second wait after clearing git-log-data-rendered markers following revert
- This gives UI time to start refreshing before we check for the new marker
- Fixes CI timing issue where revert operation needs more time to trigger UI refresh

* Update test log markers for git log refresh events

Replaces '[test-id-git-log-data-rendered]' with '[test-id-git-log-refreshed]' in gitLog.feature to better reflect UI refresh events after commit and revert actions. Adds a debug log marker '[test-id-git-revert-complete]' in revertCommit for improved test synchronization.

* Fix git revert refresh timing - remove intermediate step and rely on git-log-refreshed

* Add detailed logging to handleRevert for CI debugging

* Fix git log refresh by adding manual triggerRefresh fallback

- Add triggerRefresh function to useGitLogData hook for manual refresh
- Call triggerRefresh in handleCommitSuccess, handleRevertSuccess, and handleUndoSuccess
- This fixes cross-process IPC observable subscription issues where gitStateChange$
  notifications from main process may not reach renderer process reliably
- Add detailed logging to handleRevert for CI debugging

* Update index.tsx
2026-01-10 23:57:59 +08:00

210 lines
14 KiB
Gherkin

Feature: Sub-Wiki Functionality
As a user
I want sub-wikis to properly load tiddlers on startup
And I want to use tag tree filtering to organize tiddlers into sub-wikis
So that my content is automatically organized
@file-watching @subwiki
Scenario: Tiddler with tag saves to sub-wiki folder
# Setup: Create sub-wiki with tag BEFORE launching the app (fast setup)
Given I cleanup test wiki so it could create a new one on start
And I setup a sub-wiki "SubWiki" with tag "TestTag" and tiddlers:
| title | tags | content |
| TestTag | TestTag | Tag tiddler stub |
When I launch the TidGi application
And I wait for the page to load completely
Then I should see "page body and workspaces" elements with selectors:
| div[data-testid^='workspace-']:has-text('wiki') |
| div[data-testid^='workspace-']:has-text('SubWiki') |
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for SSE and watch-fs to be ready
# Create tiddler with tag to test routing to sub-wiki folder
When I create a tiddler "TestTiddlerTitle" with tag "TestTag" in browser view
And I wait for 3 seconds for "tiddler to be saved and routed to sub-wiki"
# Verify the tiddler file exists in sub-wiki folder after save
Then file "TestTiddlerTitle.tid" should exist in "{tmpDir}/SubWiki"
# Verify tiddler is NOT in main wiki tiddlers folder
Then file "TestTiddlerTitle.tid" should not exist in "{tmpDir}/wiki/tiddlers"
# Test SSE is still working - modify a main wiki tiddler
When I modify file "{tmpDir}/wiki/tiddlers/Index.tid" to contain "Main wiki content modified after SubWiki creation"
Then I wait for tiddler "Index" to be updated by watch-fs
Then I should see a "Index tiddler" element in browser view with selector "div[data-tiddler-title='Index']"
Then I should see "Main wiki content modified after SubWiki creation" in the browser view content
# Test modification in sub-wiki folder
When I modify file "{tmpDir}/SubWiki/TestTiddlerTitle.tid" to contain "Content modified in SubWiki folder"
And I wait for 2 seconds for "watch-fs to detect file change in sub-wiki"
When I open tiddler "TestTiddlerTitle" in browser view
And I wait for 1 seconds
Then I should see "Content modified in SubWiki folder" in the browser view content
@subwiki @subwiki-load
Scenario: Sub-wiki tiddlers are loaded on initial wiki startup
# Setup: Create sub-wiki folder and settings BEFORE launching the app
Given I cleanup test wiki so it could create a new one on start
And I setup a sub-wiki "SubWikiPreload" with tag "PreloadTag" and tiddlers:
| title | tags | content |
| PreExistingTiddler | PreloadTag | Content from pre-existing sub-wiki tiddler |
# Now launch the app - it should load both main wiki and sub-wiki tiddlers
When I launch the TidGi application
And I wait for the page to load completely
Then I should see "page body and workspaces" elements with selectors:
| div[data-testid^='workspace-']:has-text('wiki') |
| div[data-testid^='workspace-']:has-text('SubWikiPreload') |
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for SSE and watch-fs to be ready
# Open the tiddler directly using TiddlyWiki API
When I open tiddler "PreExistingTiddler" in browser view
And I wait for 0.5 seconds
# Verify the tiddler content is displayed
Then I should see "Content from pre-existing sub-wiki tiddler" in the browser view content
# Verify the tiddler has the correct tag
Then I should see a "PreloadTag tag" element in browser view with selector "[data-tiddler-title='PreExistingTiddler'] [data-tag-title='PreloadTag']"
@subwiki @subwiki-tagtree
Scenario: Tiddlers matching tag tree are routed to sub-wiki with includeTagTree enabled
# Setup: Create sub-wiki with includeTagTree enabled, and pre-existing tag hierarchy A->B
# TagTreeRoot is the sub-wiki's tagName
# TiddlerA has tag "TagTreeRoot" (direct child)
# TiddlerB has tag "TiddlerA" (grandchild via tag tree)
Given I cleanup test wiki so it could create a new one on start
And I setup a sub-wiki "SubWikiTagTree" with tag "TagTreeRoot" and includeTagTree enabled and tiddlers:
| title | tags | content |
| TiddlerA | TagTreeRoot | TiddlerA with TagTreeRoot tag |
| TiddlerB | TiddlerA | TiddlerB with TiddlerA tag |
# Now launch the app
When I launch the TidGi application
And I wait for the page to load completely
Then I should see "page body and workspaces" elements with selectors:
| div[data-testid^='workspace-']:has-text('wiki') |
| div[data-testid^='workspace-']:has-text('SubWikiTagTree') |
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for SSE and watch-fs to be ready
# Verify TiddlerA and TiddlerB were loaded from sub-wiki by opening them
When I open tiddler "TiddlerA" in browser view
And I wait for 0.5 seconds
Then I should see "TiddlerA with TagTreeRoot tag" in the browser view content
When I open tiddler "TiddlerB" in browser view
And I wait for 0.5 seconds
Then I should see "TiddlerB with TiddlerA tag" in the browser view content
# Create TiddlerC with tag TiddlerB (testing tag tree routing: TiddlerC -> TiddlerB -> TiddlerA -> TagTreeRoot)
When I create a tiddler "TiddlerC" with tag "TiddlerB" in browser view
And I wait for 3 seconds for "TiddlerC to be saved via tag tree routing"
# Verify TiddlerC is saved to sub-wiki via tag tree (TiddlerB -> TiddlerA -> TagTreeRoot)
Then file "TiddlerC.tid" should exist in "{tmpDir}/SubWikiTagTree"
Then file "TiddlerC.tid" should not exist in "{tmpDir}/wiki/tiddlers"
@subwiki @subwiki-filter
Scenario: Tiddlers matching custom filter are routed to sub-wiki
# Setup: Create sub-wiki with custom filter that matches tiddlers with "filtertest" field
Given I cleanup test wiki so it could create a new one on start
And I setup a sub-wiki "SubWikiFilter" with tag "FilterTag" and filter "[has[filtertest]]" and tiddlers:
| title | tags | content |
| FilterTiddlerA | FilterTag | TiddlerA matched by filter |
When I launch the TidGi application
And I wait for the page to load completely
Then I should see "page body and workspaces" elements with selectors:
| div[data-testid^='workspace-']:has-text('wiki') |
| div[data-testid^='workspace-']:has-text('SubWikiFilter') |
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for SSE and watch-fs to be ready
# Create a tiddler with the "filtertest" field to test filter routing
When I create a tiddler "FilterMatchTiddler" with field "filtertest" set to "yes" in browser view
And I wait for 3 seconds for "FilterMatchTiddler to be saved via filter routing"
# Verify FilterMatchTiddler is saved to sub-wiki via filter
Then file "FilterMatchTiddler.tid" should exist in "{tmpDir}/SubWikiFilter"
Then file "FilterMatchTiddler.tid" should not exist in "{tmpDir}/wiki/tiddlers"
@subwiki @subwiki-settings-ui
Scenario: Sub-wiki settings UI can enable includeTagTree option
# This tests the EditWorkspace UI for setting includeTagTree via the new switch
Given I cleanup test wiki so it could create a new one on start
And I setup a sub-wiki "SubWikiSettings" with tag "SettingsTag" and tiddlers:
| title | tags | content |
| SettingsTiddler | SettingsTag | Settings test tiddler |
When I launch the TidGi application
And I wait for the page to load completely
Then I should see "page body and workspaces" elements with selectors:
| div[data-testid^='workspace-']:has-text('wiki') |
| div[data-testid^='workspace-']:has-text('SubWikiSettings') |
# Open the edit workspace window using existing step
When I open edit workspace window for workspace with name "SubWikiSettings"
And I switch to "editWorkspace" window
And I wait for the page to load completely
And I wait for 1 seconds for "page to fully render"
# For sub-wikis, the accordion is defaultExpanded, so we should see the switch immediately
Then I should see a "sub-workspace options accordion" element with selector "[data-testid='preference-section-subWorkspaceOptions']"
# The includeTagTree switch should be visible for sub-wikis (accordion is already expanded)
Then I should see a "includeTagTree switch" element with selector "[data-testid='include-tag-tree-switch']"
# Enable includeTagTree option
When I click on a "includeTagTree switch" element with selector "[data-testid='include-tag-tree-switch']"
And I wait for 0.5 seconds
# Save the changes by clicking the save button
When I click on a "save button" element with selector "[data-testid='edit-workspace-save-button']"
Then I should not see a "save button" element with selector "[data-testid='edit-workspace-save-button']"
And I wait for 0.5 seconds for "settings to be written"
# Verify the setting was saved to settings.json
Then settings.json should have workspace "SubWikiSettings" with "includeTagTree" set to "true"
@subwiki @subwiki-create-ui
Scenario: Create sub-wiki workspace via UI
# This tests creating a sub-wiki through the Add Workspace UI
Given I cleanup test wiki so it could create a new one on start
And I launch the TidGi application
And I wait for the page to load completely
Then I should see a "default wiki workspace" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
# Enable file system watch for testing (default is false in production)
When I update workspace "wiki" settings:
| property | value |
| enableFileSystemWatch | true |
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for SSE and watch-fs to be ready
# Create sub-workspace via UI
When I click on an "add workspace button" element with selector "#add-workspace-button"
And I switch to "addWorkspace" window
# Toggle to sub-workspace mode by clicking the switch
And I click on a "main/sub workspace switch" element with selector "[data-testid='main-sub-workspace-switch']"
# Select the first (default) wiki workspace from dropdown
And I select "wiki" from MUI Select with test id "main-wiki-select"
# Type folder name
And I type "SubWikiUI" in "sub wiki folder name input" element with selector "input[aria-describedby*='-helper-text'][value='wiki']"
# Add tag using Autocomplete - type and press Enter to add the tag
And I type "UITestTag" in "tag name input" element with selector "[data-testid='tagname-autocomplete-input']"
And I press "Enter" key
And I click on a "create sub workspace button" element with selector "button.MuiButton-colorSecondary"
And I switch to "main" window
Then I should see a "SubWikiUI workspace" element with selector "div[data-testid^='workspace-']:has-text('SubWikiUI')"
# Wait for main wiki to restart after sub-wiki creation
Then I wait for "main wiki restarted after sub-wiki creation" log marker "[test-id-MAIN_WIKI_RESTARTED_AFTER_SUBWIKI]"
And I wait for "watch-fs stabilized after restart" log marker "[test-id-WATCH_FS_STABILIZED]"
And I wait for "SSE ready after restart" log marker "[test-id-SSE_READY]"
Then I wait for "view loaded" log marker "[test-id-VIEW_LOADED]"
# Wait for TiddlyWiki to fully render the page (site title appears)
Then I wait for "site title" element in browser view with selector "h1.tc-site-title"
# Click SubWikiUI workspace to see the missing tag tiddler message
When I click on a "SubWikiUI workspace button" element with selector "div[data-testid^='workspace-']:has-text('SubWikiUI')"
# Verify UITestTag text is visible (missing tiddler message shows the title)
Then I should see "UITestTag" in the browser view content
# Verify the sub-wiki was created in settings.json
Then settings.json should have workspace "SubWikiUI" with "tagNames" containing "UITestTag"