diff --git a/src/main/engine/ImportExecutionEngine.ts b/src/main/engine/ImportExecutionEngine.ts index ce8e38c..04a932d 100644 --- a/src/main/engine/ImportExecutionEngine.ts +++ b/src/main/engine/ImportExecutionEngine.ts @@ -267,10 +267,16 @@ export class ImportExecutionEngine extends EventEmitter { options: ImportExecutionOptions, progress: (phase: string, current: number, total: number, detail?: string) => void ): Promise { - const total = report.posts.items.length; + // Filter to only actual posts (postType === 'post'), skip nav_menu_item, revision, etc. + const postsToImport = report.posts.items.filter(item => item.wxrPost.postType === 'post'); + const total = postsToImport.length; - for (let i = 0; i < report.posts.items.length; i++) { - const analyzed = report.posts.items[i]; + // Count skipped "other" post types + const skippedOther = report.posts.items.length - postsToImport.length; + result.posts.skipped += skippedOther; + + for (let i = 0; i < postsToImport.length; i++) { + const analyzed = postsToImport[i]; progress('posts', i + 1, total, `Processing: ${analyzed.wxrPost.title}`); try { diff --git a/tests/assets/import-test-cases.wxr b/tests/assets/import-test-cases.wxr index 96424fb..8f32359 100644 --- a/tests/assets/import-test-cases.wxr +++ b/tests/assets/import-test-cases.wxr @@ -45,6 +45,11 @@ 6. PAGE IMPORT - Page ID 501: Standard page → becomes post with "page" category - Page ID 502: Page with HTML content for conversion test + + 7. OTHER POST TYPES (should be analyzed but NOT imported) + - Post ID 601: nav_menu_item → analyzed but skipped + - Post ID 602: revision → analyzed but skipped + - Post ID 603: wp_template → analyzed but skipped --> ]]> 0 + + + + + + + + Home Menu Link + https://testblog.example.com/home-menu/ + Mon, 01 Jan 2024 00:00:00 +0000 + + + 601 + 2024-01-01 00:00:00 + 2024-01-01 00:00:00 + 2024-01-01 00:00:00 + 2024-01-01 00:00:00 + home-menu-link + publish + nav_menu_item + 0 + + + + + HTML Formatting Test: Basic Text Styles (Revision) + https://testblog.example.com/?p=602 + Mon, 01 Jan 2024 09:00:00 +0000 + + Old revision content that should be ignored.

]]>
+ 602 + 2024-01-01 09:00:00 + 2024-01-01 09:00:00 + 2024-01-01 09:00:00 + 2024-01-01 09:00:00 + 101-revision-v1 + inherit + revision + 101 +
+ + + + Single Post Template + https://testblog.example.com/wp_template/single/ + Tue, 02 Jan 2024 00:00:00 +0000 + + + +]]> + 603 + 2024-01-02 00:00:00 + 2024-01-02 00:00:00 + 2024-01-02 00:00:00 + 2024-01-02 00:00:00 + single + publish + wp_template + 0 + +
diff --git a/tests/engine/ImportExecutionEngine.e2e.test.ts b/tests/engine/ImportExecutionEngine.e2e.test.ts index 81dccb3..782f968 100644 --- a/tests/engine/ImportExecutionEngine.e2e.test.ts +++ b/tests/engine/ImportExecutionEngine.e2e.test.ts @@ -11,6 +11,7 @@ * 4. Conflict Resolution - verifies ignore/overwrite/import behaviors * 5. Media Import - verifies media file handling with post linkage * 6. Page Import - verifies pages become posts with "page" category + * 7. Other Post Types - verifies nav_menu_item, revision, wp_template are analyzed but not imported */ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; @@ -1375,4 +1376,145 @@ describe('ImportExecutionEngine E2E Tests', () => { expect(result.wpIdToPostId.size).toBeGreaterThanOrEqual(2); // post1, post3 }); }); + + // ========================================================================== + // SECTION 7: OTHER POST TYPES (analyzed but not imported) + // ========================================================================== + + describe('Other Post Types (analyzed but not imported)', () => { + it('should include nav_menu_item, revision, and wp_template in WXR parsed data', () => { + // Verify the WXR parser includes these in the posts array + const navMenuItem = wxrData.posts.find(p => p.wpId === 601); + const revision = wxrData.posts.find(p => p.wpId === 602); + const wpTemplate = wxrData.posts.find(p => p.wpId === 603); + + expect(navMenuItem).toBeDefined(); + expect(navMenuItem!.postType).toBe('nav_menu_item'); + expect(navMenuItem!.title).toBe('Home Menu Link'); + + expect(revision).toBeDefined(); + expect(revision!.postType).toBe('revision'); + expect(revision!.slug).toBe('101-revision-v1'); + + expect(wpTemplate).toBeDefined(); + expect(wpTemplate!.postType).toBe('wp_template'); + expect(wpTemplate!.title).toBe('Single Post Template'); + }); + + it('should include other post types in analysis report but skip them during import', async () => { + // Find the "other" post types from parsed WXR + const navMenuItem = wxrData.posts.find(p => p.wpId === 601)!; + const revision = wxrData.posts.find(p => p.wpId === 602)!; + const wpTemplate = wxrData.posts.find(p => p.wpId === 603)!; + + // Also include a regular post to verify it gets imported + const regularPost = wxrData.posts.find(p => p.wpId === 101)!; + + // Create analysis report that includes both regular posts and "other" post types + const report: ImportAnalysisReport = { + wxrData: wxrData, + posts: { + total: 4, + new: 4, + update: 0, + conflict: 0, + items: [ + { + wxrPost: regularPost, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash1', + markdownPreview: '', + }, + { + wxrPost: navMenuItem, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash2', + markdownPreview: '', + }, + { + wxrPost: revision, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash3', + markdownPreview: '', + }, + { + wxrPost: wpTemplate, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash4', + markdownPreview: '', + }, + ], + }, + pages: { total: 0, new: 0, update: 0, conflict: 0, items: [] }, + media: { total: 0, new: 0, update: 0, conflict: 0, missing: 0, items: [] }, + tags: [], + categories: [], + site: wxrData.site, + macros: { totalUniqueMacros: 0, totalMacroUsages: 0, allMapped: true, macros: [] }, + }; + + const result = await engine.executeImport(report, {}); + + // Verify only the regular post was imported + expect(result.posts.imported).toBe(1); + + // The 3 "other" post types should be skipped + expect(result.posts.skipped).toBe(3); + expect(result.posts.errors).toBe(0); + + // Verify only one post was actually written to database/filesystem + expect(insertedPosts.length).toBe(1); + expect(insertedPosts[0].slug).toBe('html-formatting-basic'); + + // Verify no files were written for nav_menu_item, revision, or wp_template + const writtenSlugs = writtenFiles.map(f => f.path); + expect(writtenSlugs.some(p => p.includes('home-menu-link'))).toBe(false); + expect(writtenSlugs.some(p => p.includes('101-revision-v1'))).toBe(false); + expect(writtenSlugs.some(p => p.includes('single'))).toBe(false); + }); + + it('should correctly count skipped "other" types in result summary', async () => { + // Test with only "other" post types to verify counting + const navMenuItem = wxrData.posts.find(p => p.wpId === 601)!; + const revision = wxrData.posts.find(p => p.wpId === 602)!; + + const report: ImportAnalysisReport = { + wxrData: wxrData, + posts: { + total: 2, + new: 2, + update: 0, + conflict: 0, + items: [ + { + wxrPost: navMenuItem, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash1', + markdownPreview: '', + }, + { + wxrPost: revision, + status: 'new' as PostAnalysisStatus, + contentHash: 'hash2', + markdownPreview: '', + }, + ], + }, + pages: { total: 0, new: 0, update: 0, conflict: 0, items: [] }, + media: { total: 0, new: 0, update: 0, conflict: 0, missing: 0, items: [] }, + tags: [], + categories: [], + site: wxrData.site, + macros: { totalUniqueMacros: 0, totalMacroUsages: 0, allMapped: true, macros: [] }, + }; + + const result = await engine.executeImport(report, {}); + + // All should be skipped, none imported + expect(result.posts.imported).toBe(0); + expect(result.posts.skipped).toBe(2); + expect(result.posts.errors).toBe(0); + expect(insertedPosts.length).toBe(0); + }); + }); });