Skip to content

Commit

Permalink
feat(teach): re-add substitute flag, fix #147
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Mar 9, 2021
1 parent 2029ad5 commit b42773b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 10 deletions.
34 changes: 32 additions & 2 deletions packages/plugin-teach/src/plugins/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ declare module '../utils' {
interface DialogueTest {
writer?: string
frozen?: boolean
substitute?: boolean
}

interface Dialogue {
Expand Down Expand Up @@ -34,8 +35,11 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
.option('frozen', '-F, --no-frozen 解锁这个问答', { authority: authority.frozen, value: false })
.option('writer', '-w <uid:user> 添加或设置问题的作者')
.option('writer', '-W, --anonymous 添加或设置匿名问题', { authority: authority.writer, value: '' })
.option('substitute', '-s 由教学者完成问答的执行')
.option('substitute', '-S, --no-substitute 由触发者完成问答的执行', { value: false })

ctx.emit('dialogue/flag', 'frozen')
ctx.emit('dialogue/flag', 'substitute')

ctx.before('dialogue/detail', async (argv) => {
argv.nameMap = {}
Expand Down Expand Up @@ -87,6 +91,9 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
if (writer) {
const name = argv.nameMap[writer]
output.push(name ? `来源:${name}` : `来源:未知用户`)
if (flag & Dialogue.Flag.substitute) {
output.push('回答中的指令由教学者代行。')
}
}
})

Expand All @@ -95,17 +102,23 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
// 当使用 -w 时需要原作者权限高于目标用户
// 锁定的问答需要 frozen 级权限才能修改
ctx.on('dialogue/permit', ({ session, target, options, authMap }, { writer, flag }) => {
const { writer: newWriter } = options
const { substitute, writer: newWriter } = options
const { id, authority } = session.user
return (
(newWriter && authority <= authMap[newWriter] && newWriter !== id) ||
((flag & Dialogue.Flag.frozen) && authority < config.authority.frozen) ||
(writer !== id && target && authority < config.authority.admin)
(writer !== id && (
(target && authority < config.authority.admin) || (
(substitute || (flag & Dialogue.Flag.substitute)) &&
(authority <= (authMap[writer] || config.authority.base))
)
))
)
})

ctx.on('dialogue/detail-short', ({ flag }, output) => {
if (flag & Dialogue.Flag.frozen) output.push('锁定')
if (flag & Dialogue.Flag.substitute) output.push('代行')
})

ctx.before('dialogue/search', ({ writer }, test) => {
Expand All @@ -123,4 +136,21 @@ export default function apply(ctx: Context, config: Dialogue.Config) {
data.writer = session.user.id
}
})

// 触发代行者模式
ctx.on('dialogue/before-send', async (state) => {
const { dialogue, session } = state
if (dialogue.flag & Dialogue.Flag.substitute && dialogue.writer && session.user.id !== dialogue.writer) {
const userFields = new Set<User.Field>(['id'])
ctx.app.emit(session, 'dialogue/before-attach-user', state, userFields)
// do a little trick here
const { platform, userId } = session
session.platform = 'id' as never
session.userId = dialogue.writer
session.user = null
await session.observeUser(userFields)
session.platform = platform
session.userId = userId
}
})
}
30 changes: 22 additions & 8 deletions packages/plugin-teach/tests/writer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import createEnvironment from './environment'
import jest from 'jest-mock'

const DETAIL_HEAD = '编号为 1 的问答信息:\n问题:foo\n回答:bar\n'
const DETAIL_HEAD_QES = '编号为 1 的问答信息:\n问题:foo\n'
const DETAIL_HEAD = DETAIL_HEAD_QES + '回答:bar\n'
const SEARCH_HEAD = '问题“foo”的回答如下:\n'

describe('Teach Plugin - Writer', () => {
const { app, u2, u3g1, u4g2 } = createEnvironment({ useWriter: true })
const { app, u2g1, u3g1, u4g2 } = createEnvironment({ useWriter: true })

app.command('test').action(({ session }) => '' + session.userId)

Expand All @@ -22,7 +23,7 @@ describe('Teach Plugin - Writer', () => {
})

it('modify writer', async () => {
await u2.shouldReply('#1 -W', '问答 1 因权限过低无法修改。')
await u2g1.shouldReply('#1 -W', '问答 1 因权限过低无法修改。')
await u4g2.shouldReply('#1 -w foo', '选项 writer 输入无效,请指定正确的用户。')
await u4g2.shouldReply('#1 -w [CQ:at,id=500]', '指定的目标用户不存在。')
await u4g2.shouldReply('#1 -w [CQ:at,id=200]', '问答 1 已成功修改。')
Expand All @@ -36,11 +37,11 @@ describe('Teach Plugin - Writer', () => {
})

it('anonymous', async () => {
u2.meta.author.username = 'nick2'
await u2.shouldReply('#1', DETAIL_HEAD + '来源:nick2 (200)')
await u2.shouldReply('#1 -W', '问答 1 已成功修改。')
await u2.shouldReply('#1', DETAIL_HEAD.slice(0, -1))
await u2.shouldReply('#1 -p 0', '问答 1 因权限过低无法修改。')
u2g1.meta.author.username = 'nick2'
await u2g1.shouldReply('#1', DETAIL_HEAD + '来源:nick2 (200)')
await u2g1.shouldReply('#1 -W', '问答 1 已成功修改。')
await u2g1.shouldReply('#1', DETAIL_HEAD.slice(0, -1))
await u2g1.shouldReply('#1 -p 0', '问答 1 因权限过低无法修改。')
})

it('frozen', async () => {
Expand All @@ -51,4 +52,17 @@ describe('Teach Plugin - Writer', () => {
await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [锁定] bar')
await u4g2.shouldReply('#1 -F', '问答 1 已成功修改。')
})

it('substitute', async () => {
app.command('bar', { authority: 3 }).action(() => 'test')
await u3g1.shouldReply('#1 ~ $(bar) -w @300', '问答 1 已成功修改。')
const DETAIL_SPECIAL = DETAIL_HEAD_QES + '回答:$(bar)\n来源:user3 (300)'
await u3g1.shouldReply('#1', DETAIL_SPECIAL)
await u2g1.shouldReply('foo', '权限不足。')

await u3g1.shouldReply('#1 -s', '问答 1 已成功修改。')
await u3g1.shouldReply('#1', DETAIL_SPECIAL + '\n回答中的指令由教学者代行。')
await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [代行] $(bar)')
await u2g1.shouldReply('foo', 'test')
})
})

0 comments on commit b42773b

Please sign in to comment.