### TL;DR
* Fix the issue of inaccurate content replacement in AI Replace Selection
* Optimize unit Tests utils
### What Changed
1. Fixed the issue of inaccurate content replacement in AI Replace Selection:
- Convert the AI Answer into a Snapshot, then transform it into a sequence of Blocks ready for insertion.
- Invoke the `replaceSelectedTextWithBlocks` command to replace the current selection with blocks (given the complexity of block combinations, this command uses [ts-pattern](https://github.com/gvergnaud/ts-pattern) implementation to ensure compile-time prevention of pattern handling omissions).
2. Optimized unit test assertions for commands, now allowing direct document content comparison using `toEqualDoc`.
```ts
const host = affine`
<affine-page id="page">
<affine-note id="note">
<affine-paragraph id="paragraph-1">Hel<anchor />lo</affine-paragraph>
<affine-paragraph id="paragraph-2">Wor<focus />ld</affine-paragraph>
</affine-note>
</affine-page>
`;
// ....
const expected = affine`
<affine-page id="page">
<affine-note id="note">
<affine-paragraph id="paragraph-1">Hel111</affine-paragraph>
<affine-code id="code"></affine-code>
<affine-paragraph id="paragraph-2">222ld</affine-paragraph>
</affine-note>
</affine-page>
`;
expect(host.doc).toEqualDoc(expected.doc);
```
3. Added support for text cursors in unit test template syntax.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
> CLOSE BS-3278
- **New Features**
- Introduced the ability to replace selected text in documents with blocks, supporting advanced merging and insertion scenarios for various block types.
- **Bug Fixes**
- Improved handling of text selection and cursor placement in document templates used for testing.
- **Tests**
- Added comprehensive tests for replacing selected text with blocks, including edge cases and complex selection scenarios.
- Enhanced test utilities for document structure comparison and selection handling.
- Updated end-to-end tests to verify correct replacement of selected text via AI-driven actions.
- **Chores**
- Added and updated dependencies to support new features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **Refactor**
- Unified internal data access by replacing all references from `doc` to `store` across all components, blocks, widgets, and utilities. This affects how readonly state, block operations, and service retrieval are handled throughout the application.
- **Tests**
- Updated all test utilities and test cases to use `store` instead of `doc` for document-related operations.
- **Chores**
- Updated context providers and property names to reflect the change from `doc` to `store` for improved consistency and maintainability.
No user-facing features or behaviors have changed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
### TL;DR
Added unit tests for block and selection commands, along with a new test helper system for creating test documents.
### What changed?
- Added unit tests for several commands:
- `getFirstContentBlockCommand`
- `getLastContentBlockCommand`
- `isNothingSelectedCommand`
- Created a new test helpers make it easier to create structured test documents with a html-like syntax:
```typescript
import { describe, expect, it } from 'vitest';
import { affine } from '../__tests__/utils/affine-template';
describe('My Test', () => {
it('should correctly handle document structure', () => {
const doc = affine`
<affine-page>
<affine-note>
<affine-paragraph>Test content</affine-paragraph>
</affine-note>
</affine-page>
`;
// Get blocks
const pages = doc.getBlocksByFlavour('affine:page');
const notes = doc.getBlocksByFlavour('affine:note');
const paragraphs = doc.getBlocksByFlavour('affine:paragraph');
expect(pages.length).toBe(1);
expect(notes.length).toBe(1);
expect(paragraphs.length).toBe(1);
// Perform more tests here...
});
});
```
### TL;DR
Added a new command to check if nothing is currently selected in the editor.
### What changed?
- Created new `isNothingSelectedCommand` to determine if there are no active selections
### TL;DR
Added new commands to retrieve the first and last content blocks in a document.
### What changed?
- Created `getFirstContentBlockCommand` to find the first content block in a document
- Created `getLastContentBlockCommand` to find the last content block in a document
- Added `getFirstNoteBlock` utility function to find the first note block in a document