feat: publish Dever core with project scaffolding and versioned AI skills
This commit is contained in:
1 parent
70fa73cdc2
commit
ac458ffa7f
960 files changed
+221319
-1163
No files matched your search
@@ -0,0 +1,32 @@
|
||||
# content.category.lifecycle
|
||||
|
||||
验证分类创建、规范化、活动状态读取及停用对独立分类的隔离。停用分类的关联拒绝由 HTTP 验收覆盖。
|
||||
|
||||
- 包:`content.category.lifecycle`
|
||||
- 公开类型:无
|
||||
- 公开方法:无
|
||||
- 使用:无
|
||||
|
||||
## lifecycle
|
||||
|
||||
通过真实 App 操作分类,并核对独立分类的标识和可用状态。
|
||||
|
||||
- 函数:`lifecycle`
|
||||
- 输入:无
|
||||
- 输出:无
|
||||
|
||||
```dever
|
||||
lifecycle() () {
|
||||
category = app.create(" Dever News ")
|
||||
assert_eq(category.name, "Dever News")
|
||||
assert_eq(category.slug, "dever news")
|
||||
assert_eq(category.status, "active")
|
||||
app.require_active(category.id)
|
||||
app.require_active(null)
|
||||
assert(app.disable(category.id))
|
||||
independent = app.create("Announcements")
|
||||
assert(independent.id != category.id)
|
||||
assert_eq(independent.slug, "announcements")
|
||||
app.require_active(independent.id)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
# 文章发布测试
|
||||
|
||||
验证文章标识和标题规范化、分页边界,以及合法发布条件。数据库发布、权限拒绝和版本冲突由 HTTP 验收覆盖。
|
||||
|
||||
- 包:`news.article.publish`
|
||||
- 公开类型:无
|
||||
- 公开方法:无
|
||||
- 使用:无
|
||||
|
||||
## 发布
|
||||
|
||||
通过真实 Domain 调用核对规范化结果和合法边界。
|
||||
|
||||
- 函数:`publish`
|
||||
- 输入:无
|
||||
- 输出:无
|
||||
|
||||
```dever
|
||||
publish() () {
|
||||
assert_eq(domain.normalize_slug(" News-Article "), "news-article")
|
||||
assert_eq(domain.normalize_title(" First article "), "First article")
|
||||
assert_eq(domain.page_size(1), 1)
|
||||
assert_eq(domain.page_size(100), 100)
|
||||
domain.require_owner(true)
|
||||
domain.require_draft(true)
|
||||
domain.require_updated(1)
|
||||
domain.require_content("news", "Title", "Body")
|
||||
domain.require_published(true)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
# 平台初始化测试
|
||||
|
||||
在运行器隔离的数据库中建立租户、用户主体和私密凭据,读取所有者成员关系并核对不同租户的标识。
|
||||
|
||||
- 包:`user.account.bootstrap`
|
||||
- 公开类型:无
|
||||
- 公开方法:无
|
||||
- 使用:无
|
||||
|
||||
## 初始化平台账户
|
||||
|
||||
本节定义对应的源码合同。
|
||||
|
||||
- 函数:`bootstrap`
|
||||
- 输入:无
|
||||
- 输出:无
|
||||
|
||||
```dever
|
||||
bootstrap() () {
|
||||
created = user.account.bootstrap(
|
||||
"tenant-one",
|
||||
"Tenant One",
|
||||
" owner@example.com ",
|
||||
" Owner ",
|
||||
secret("correct horse battery staple")
|
||||
)
|
||||
user.membership.require_active(created.user_id, created.tenant_id)
|
||||
user.account.active(created.user_id)
|
||||
tenant = platform.tenant.active("tenant-one")
|
||||
assert_eq(tenant.id, created.tenant_id)
|
||||
assert_eq(tenant.key, "tenant-one")
|
||||
unrelated = platform.tenant.provision("tenant-two", "Tenant Two")
|
||||
assert(unrelated.id != created.tenant_id)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
# user.account.validation
|
||||
|
||||
验证账户邮箱和显示名称规范化,包括中文名称。非法请求由 HTTP 验收覆盖。
|
||||
|
||||
- 包:`user.account.validation`
|
||||
- 公开类型:无
|
||||
- 公开方法:无
|
||||
- 使用:无
|
||||
|
||||
## validation
|
||||
|
||||
核对真实 Domain 返回的规范化字段。
|
||||
|
||||
- 函数:`validation`
|
||||
- 输入:无
|
||||
- 输出:无
|
||||
|
||||
```dever
|
||||
validation() () {
|
||||
prepared = domain.prepare(" OWNER@EXAMPLE.COM ", " Owner ")
|
||||
assert_eq(prepared.address, "owner@example.com")
|
||||
assert_eq(prepared.name, "Owner")
|
||||
unicode_name = domain.prepare("editor@example.com", " 编辑员 ")
|
||||
assert_eq(unicode_name.address, "editor@example.com")
|
||||
assert_eq(unicode_name.name, "编辑员")
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,56 @@
|
||||
# 会话生命周期测试
|
||||
|
||||
在隔离数据库中核对会话身份字段,执行撤销和虚拟时钟清理,再验证独立新会话。旧会话拒绝由 HTTP 验收覆盖。
|
||||
|
||||
- 包:`user.session.lifecycle`
|
||||
- 公开类型:无
|
||||
- 公开方法:无
|
||||
- 使用:无
|
||||
|
||||
## lifecycle
|
||||
|
||||
通过真实 Session App 核对创建、读取和清理后的独立使用。
|
||||
|
||||
- 函数:`lifecycle`
|
||||
- 输入:无
|
||||
- 输出:无
|
||||
|
||||
```dever
|
||||
lifecycle() () {
|
||||
account = user.account.bootstrap(
|
||||
"sessions",
|
||||
"Sessions",
|
||||
"session@example.com",
|
||||
"Session user",
|
||||
secret("correct horse battery staple")
|
||||
)
|
||||
session = app.open(
|
||||
"session-subject",
|
||||
account.user_id,
|
||||
account.tenant_id,
|
||||
"sessions",
|
||||
"admin"
|
||||
)
|
||||
authenticated = app.authenticate(session.uuid, "admin")
|
||||
assert_eq(authenticated.subject, "session-subject")
|
||||
assert_eq(authenticated.user_id, account.user_id)
|
||||
assert_eq(authenticated.tenant_id, account.tenant_id)
|
||||
assert_eq(authenticated.tenant_key, "sessions")
|
||||
app.revoke(session.uuid)
|
||||
dever.test.advance_clock(3600000)
|
||||
app.cleanup()
|
||||
replacement = app.open(
|
||||
"new-subject",
|
||||
account.user_id,
|
||||
account.tenant_id,
|
||||
"sessions",
|
||||
"front"
|
||||
)
|
||||
assert(replacement.uuid != session.uuid)
|
||||
current = app.authenticate(replacement.uuid, "front")
|
||||
assert_eq(current.subject, "new-subject")
|
||||
assert_eq(current.user_id, account.user_id)
|
||||
assert_eq(current.tenant_id, account.tenant_id)
|
||||
assert_eq(current.tenant_key, "sessions")
|
||||
}
|
||||
```
|
||||
Reference in new issue
Block a user