Skip to content

Commit 1d40fb5

Browse files
guo-yuclaude
andcommitted
v1.4.1: full e2e coverage for all 3 providers + README test matrix
Add comprehensive e2e tests: db9 full flow (18 tests), remote OSS/hosted direction filter + pagination, sqlite CLI integration (11 tests). Update all 3 READMEs (EN/ZH/JA) with provider e2e coverage matrix. 239 tests total (168 unit + 71 e2e), 0 failures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent efe99e0 commit 1d40fb5

7 files changed

Lines changed: 483 additions & 15 deletions

File tree

README.ja.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,24 @@ mails claim <name> # @mails.dev メールアドレス
9494
mails send --to <email> --subject <s> --body <text>
9595
mails send --to <email> --subject <s> --body <text> --attach file.pdf
9696
mails inbox # 最近のメール一覧
97-
mails inbox --query "キーワード" # メール検索
97+
mails inbox --query "キーワード" # 全文検索(関連性順)
9898
mails inbox <id> # メール詳細(添付ファイル含む)
9999
mails code --to <addr> --timeout 30 # 認証コード待機
100100
mails config # 設定表示
101+
102+
# 高度なフィルター(mails.dev ホスティング / db9)
103+
mails inbox --has-attachments # 添付ファイル付きのみ
104+
mails inbox --attachment-type pdf # 添付ファイルの種類で絞り込み
105+
mails inbox --from github.com # 送信者で絞り込み
106+
mails inbox --since 2026-03-01 --until 2026-03-20 # 期間指定
107+
mails inbox --header "X-Mailer:sendgrid" # メールヘッダーで絞り込み
108+
109+
# 自由に組み合わせ可能
110+
mails inbox --from github.com --has-attachments --since 2026-03-13
111+
mails inbox --query "デプロイ" --attachment-type log --direction inbound
112+
113+
# 送信者統計
114+
mails stats senders # 送信者の頻度ランキング
101115
```
102116

103117
## SDK
@@ -113,9 +127,16 @@ await send({
113127
attachments: [{ path: './report.pdf' }],
114128
})
115129

116-
// 受信箱検索
130+
// 受信箱検索(全文検索、関連性順)
117131
const results = await searchInbox('agent@mails.dev', { query: 'パスワードリセット' })
118132

133+
// 高度なフィルター(mails.dev ホスティング / db9)
134+
const pdfs = await getInbox('agent@mails.dev', {
135+
has_attachments: true,
136+
attachment_type: 'pdf',
137+
since: '2026-03-01',
138+
})
139+
119140
// 認証コード待機
120141
const code = await waitForCode('agent@mails.dev', { timeout: 30 })
121142
```
@@ -144,7 +165,35 @@ const code = await waitForCode('agent@mails.dev', { timeout: 30 })
144165

145166
## テスト
146167

147-
ユニットテスト125件 + E2Eテスト42件
168+
```bash
169+
bun test # ユニット + E2Eテスト(外部依存なし)
170+
bun test:coverage # カバレッジレポート付き
171+
bun test:live # ライブE2Eテスト(.env設定が必要)
172+
bun test:all # すべてのテスト(ライブE2E含む)
173+
```
174+
175+
ユニットテスト168件 + E2Eテスト71件 = **239件のテスト**、全プロバイダーをカバー。
176+
177+
### プロバイダー別E2Eカバレッジ
178+
179+
| | SQLite | db9 | Remote (OSS) | Remote (ホスティング) |
180+
|---------------------------|--------|-------|--------------|---------------------|
181+
| inboundメール保存 ||| N/A | N/A |
182+
| メール + 添付ファイル保存 ||| N/A | N/A |
183+
| 送信 → 受信(実通信) |||||
184+
| 受信箱一覧 |||||
185+
| has_attachmentsフラグ |||||
186+
| 方向フィルター |||||
187+
| ページネーション |||||
188+
| メール詳細 |||||
189+
| 添付ファイルメタデータ |||||
190+
| 検索 |||||
191+
| 添付ファイル内容検索 |||||
192+
| 認証コード |||||
193+
| 添付ファイルダウンロード |||||
194+
| ディスクに保存 (--save) |||||
195+
| メールボックス分離 |||||
196+
| Outbound記録 ||| N/A | N/A |
148197

149198
## ライセンス
150199

README.md

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,26 @@ mails send --to <email> --subject "Report" --body "See attached" --attach report
114114
```bash
115115
mails inbox # List recent emails
116116
mails inbox --mailbox agent@test.com # Specific mailbox
117-
mails inbox --query "password reset" # Search emails
117+
mails inbox --query "password reset" # Full-text search (ranked by relevance)
118118
mails inbox --query "invoice" --direction inbound --limit 10
119119
mails inbox <id> # View email details + attachments
120+
121+
# Advanced filters (mails.dev hosted / db9)
122+
mails inbox --has-attachments # Only emails with attachments
123+
mails inbox --attachment-type pdf # Filter by attachment type
124+
mails inbox --from github.com # Filter by sender
125+
mails inbox --since 2026-03-01 --until 2026-03-20 # Time range
126+
mails inbox --header "X-Mailer:sendgrid" # Filter by email header
127+
128+
# Combine any filters
129+
mails inbox --from github.com --has-attachments --since 2026-03-13
130+
mails inbox --query "deploy" --attachment-type log --direction inbound
131+
```
132+
133+
### stats
134+
135+
```bash
136+
mails stats senders # Top senders by frequency
120137
```
121138

122139
### code
@@ -159,12 +176,19 @@ await send({
159176
// List inbox
160177
const emails = await getInbox('agent@mails.dev', { limit: 10 })
161178

162-
// Search inbox
179+
// Search inbox (full-text search with relevance ranking)
163180
const results = await searchInbox('agent@mails.dev', {
164181
query: 'password reset',
165182
direction: 'inbound',
166183
})
167184

185+
// Advanced filters (mails.dev hosted / db9)
186+
const pdfs = await getInbox('agent@mails.dev', {
187+
has_attachments: true,
188+
attachment_type: 'pdf',
189+
since: '2026-03-01',
190+
})
191+
168192
// Wait for verification code
169193
const code = await waitForCode('agent@mails.dev', { timeout: 30 })
170194
if (code) console.log(code.code) // "123456"
@@ -218,14 +242,21 @@ Local database at `~/.mails/mails.db`. Zero config.
218242

219243
### db9.ai
220244

221-
Cloud PostgreSQL for AI agents. Full-text search with ranking.
245+
Cloud PostgreSQL for AI agents. Full-text search with relevance ranking, attachment content search, and advanced filtering.
222246

223247
```bash
224248
mails config set storage_provider db9
225249
mails config set db9_token YOUR_TOKEN
226250
mails config set db9_database_id YOUR_DB_ID
227251
```
228252

253+
With db9, you get:
254+
- **Weighted FTS** — subject (highest) > sender > body > attachment text
255+
- **Attachment filters** — by type, by name, with/without attachments
256+
- **Sender & time filters**`--from`, `--since`, `--until`
257+
- **Header queries** — search JSONB email headers
258+
- **Sender stats** — frequency ranking of all senders
259+
229260
### Remote (Worker API)
230261

231262
Queries the Worker HTTP API directly. Auto-enabled when `api_key` or `worker_url` is configured.
@@ -245,12 +276,34 @@ Queries the Worker HTTP API directly. Auto-enabled when `api_key` or `worker_url
245276
## Testing
246277

247278
```bash
248-
bun test # Unit + mock E2E tests
279+
bun test # Unit + E2E tests (no external deps)
249280
bun test:coverage # With coverage report
250281
bun test:live # Live E2E with real Resend + Cloudflare (requires .env)
282+
bun test:all # All tests including live E2E
251283
```
252284

253-
125 unit tests + 42 E2E tests across 6 test suites.
285+
168 unit tests + 71 E2E tests = **239 tests** across all providers.
286+
287+
### E2E Coverage by Provider
288+
289+
| | SQLite | db9 | Remote (OSS) | Remote (Hosted) |
290+
|---------------------------|--------|-------|--------------|-----------------|
291+
| Save inbound email ||| N/A | N/A |
292+
| Save email + attachments ||| N/A | N/A |
293+
| Send → receive (real) |||||
294+
| Inbox list |||||
295+
| has_attachments flag |||||
296+
| Direction filter |||||
297+
| Pagination |||||
298+
| Email detail |||||
299+
| Attachment metadata |||||
300+
| Search |||||
301+
| Attachment content search |||||
302+
| Verification code |||||
303+
| Download attachment |||||
304+
| Save to disk (--save) |||||
305+
| Mailbox isolation |||||
306+
| Outbound recording ||| N/A | N/A |
254307

255308
## License
256309

README.zh.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,24 @@ mails claim <name> # 认领 @mails.dev 邮箱
9494
mails send --to <email> --subject <s> --body <text>
9595
mails send --to <email> --subject <s> --body <text> --attach file.pdf
9696
mails inbox # 最近邮件列表
97-
mails inbox --query "关键词" # 搜索邮件
97+
mails inbox --query "关键词" # 全文搜索(按相关性排序)
9898
mails inbox <id> # 查看邮件详情(含附件)
9999
mails code --to <addr> --timeout 30 # 等待验证码
100100
mails config # 查看配置
101+
102+
# 高级过滤(mails.dev 托管 / db9)
103+
mails inbox --has-attachments # 只看带附件的邮件
104+
mails inbox --attachment-type pdf # 按附件类型过滤
105+
mails inbox --from github.com # 按发件人过滤
106+
mails inbox --since 2026-03-01 --until 2026-03-20 # 时间范围
107+
mails inbox --header "X-Mailer:sendgrid" # 按邮件头过滤
108+
109+
# 任意组合
110+
mails inbox --from github.com --has-attachments --since 2026-03-13
111+
mails inbox --query "部署" --attachment-type log --direction inbound
112+
113+
# 发件人统计
114+
mails stats senders # 按发件人频率排行
101115
```
102116

103117
## SDK
@@ -113,9 +127,16 @@ await send({
113127
attachments: [{ path: './report.pdf' }],
114128
})
115129

116-
// 搜索收件箱
130+
// 搜索收件箱(全文搜索,按相关性排序)
117131
const results = await searchInbox('agent@mails.dev', { query: '密码重置' })
118132

133+
// 高级过滤(mails.dev 托管 / db9)
134+
const pdfs = await getInbox('agent@mails.dev', {
135+
has_attachments: true,
136+
attachment_type: 'pdf',
137+
since: '2026-03-01',
138+
})
139+
119140
// 等待验证码
120141
const code = await waitForCode('agent@mails.dev', { timeout: 30 })
121142
```
@@ -144,7 +165,35 @@ const code = await waitForCode('agent@mails.dev', { timeout: 30 })
144165

145166
## 测试
146167

147-
125 个单元测试 + 42 个 E2E 测试
168+
```bash
169+
bun test # 单元 + E2E 测试(无需外部依赖)
170+
bun test:coverage # 附带覆盖率报告
171+
bun test:live # 实时 E2E 测试(需要 .env 配置)
172+
bun test:all # 全部测试(包括实时 E2E)
173+
```
174+
175+
168 个单元测试 + 71 个 E2E 测试 = **239 个测试**,覆盖全部 Provider。
176+
177+
### 各 Provider E2E 覆盖情况
178+
179+
| | SQLite | db9 | Remote (OSS) | Remote (托管) |
180+
|---------------------------|--------|-------|--------------|---------------|
181+
| 存储 inbound 邮件 ||| N/A | N/A |
182+
| 存储邮件 + 附件 ||| N/A | N/A |
183+
| 发送 → 接收(真实链路) |||||
184+
| 收件箱列表 |||||
185+
| has_attachments 标记 |||||
186+
| 方向过滤 |||||
187+
| 分页 |||||
188+
| 邮件详情 |||||
189+
| 附件元数据 |||||
190+
| 搜索 |||||
191+
| 附件内容搜索 |||||
192+
| 验证码 |||||
193+
| 附件下载 |||||
194+
| 保存到磁盘 (--save) |||||
195+
| 邮箱隔离 |||||
196+
| Outbound 记录 ||| N/A | N/A |
148197

149198
## 许可证
150199

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mails",
3-
"version": "1.4.0",
3+
"version": "1.4.1",
44
"description": "Email infrastructure for AI agents",
55
"type": "module",
66
"main": "dist/index.js",
@@ -19,8 +19,8 @@
1919
"build:compile": "bun build src/cli/index.ts --compile --outfile mails",
2020
"dev": "bun run src/cli/index.ts",
2121
"typecheck": "tsc --noEmit",
22-
"test": "bun test test/unit test/e2e/flow.test.ts test/e2e/sqlite-search.test.ts",
23-
"test:coverage": "bun test --coverage test/unit test/e2e/flow.test.ts",
22+
"test": "bun test test/unit test/e2e/flow.test.ts test/e2e/sqlite-search.test.ts && bun test test/e2e/inbox-integration.test.ts",
23+
"test:coverage": "bun test --coverage test/unit test/e2e/flow.test.ts && bun test --coverage test/e2e/inbox-integration.test.ts",
2424
"test:live": "bun test test/e2e/live.test.ts",
2525
"test:cloud": "bun run test/e2e/cloud-e2e.ts",
2626
"test:all": "bun test"

src/cli/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async function main() {
3535
case 'version':
3636
case '--version':
3737
case '-v':
38-
console.log('mails v1.4.0')
38+
console.log('mails v1.4.1')
3939
break
4040
default:
4141
console.error(`Unknown command: ${command}`)

src/core/storage.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { createRemoteProvider } from '../providers/storage/remote.js'
66

77
let _provider: StorageProvider | null = null
88

9+
/** Reset cached provider (for testing only) */
10+
export function _resetStorage(provider?: StorageProvider) { _provider = provider ?? null }
11+
912
export async function getStorage(): Promise<StorageProvider> {
1013
if (_provider) return _provider
1114

0 commit comments

Comments
 (0)