atproto/packages/ozone/tests/settings.test.ts
Matthieu Sieben c34426fc55
Fix ozone preferences test (#3001)
use consistent ordering of insertion
2024-11-14 14:27:49 +01:00

309 lines
9.3 KiB
TypeScript

import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
import AtpAgent, {
ToolsOzoneSettingListOptions,
ToolsOzoneSettingUpsertOption,
} from '@atproto/api'
import { ids } from '../src/lexicon/lexicons'
import { SettingScope } from '../dist/db/schema/setting'
import { forSnapshot } from './_util'
describe('ozone-settings', () => {
let network: TestNetwork
let agent: AtpAgent
let sc: SeedClient
const upsertOption = async (
setting: ToolsOzoneSettingUpsertOption.InputSchema,
callerRole: 'admin' | 'moderator' | 'triage' = 'admin',
) => {
const { data } = await agent.tools.ozone.setting.upsertOption(setting, {
encoding: 'application/json',
headers: await network.ozone.modHeaders(
ids.ToolsOzoneSettingUpsertOption,
callerRole,
),
})
return data
}
const removeOptions = async (
keys: string[],
scope: SettingScope,
callerRole: 'admin' | 'moderator' | 'triage' = 'admin',
) => {
await agent.tools.ozone.setting.removeOptions(
{ keys, scope },
{
encoding: 'application/json',
headers: await network.ozone.modHeaders(
ids.ToolsOzoneSettingRemoveOptions,
callerRole,
),
},
)
}
const listOptions = async (
params: ToolsOzoneSettingListOptions.QueryParams,
callerRole: 'admin' | 'moderator' | 'triage' = 'moderator',
) => {
const { data } = await agent.tools.ozone.setting.listOptions(params, {
headers: await network.ozone.modHeaders(
ids.ToolsOzoneSettingListOptions,
callerRole,
),
})
return data
}
beforeAll(async () => {
network = await TestNetwork.create({
dbPostgresSchema: 'ozone_settings',
})
agent = network.ozone.getClient()
sc = network.getSeedClient()
await basicSeed(sc)
await network.processAll()
})
afterAll(async () => {
await network.close()
})
describe('upsertOption', () => {
afterAll(async () => {
await removeOptions(
['tools.ozone.setting.upsertTest.labelers'],
'personal',
)
})
it('only allows managerRole to update instance settings', async () => {
await upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.upsertTest.labelers',
value: { dids: ['did:plc:xyz'] },
description: 'triage users can not update this',
managerRole: 'tools.ozone.team.defs#roleModerator',
})
await expect(
upsertOption(
{
scope: 'instance',
key: 'tools.ozone.setting.upsertTest.labelers',
value: { noDids: 'test' },
description: 'triage users can not update this',
managerRole: 'tools.ozone.team.defs#roleModerator',
},
'triage',
),
).rejects.toThrow(/Not permitted/gi)
await upsertOption(
{
scope: 'instance',
key: 'tools.ozone.setting.upsertTest.labelers',
value: { noDids: 'test' },
description:
'My personal labelers that i want to use when browsing ozone',
managerRole: 'tools.ozone.team.defs#roleModerator',
},
'moderator',
)
const afterUpdatedByModerator = await listOptions(
{
scope: 'instance',
prefix: 'tools.ozone.setting.upsertTest.labelers',
},
'moderator',
)
expect(afterUpdatedByModerator.options[0].value?.['dids']).toBeFalsy()
expect(afterUpdatedByModerator.options[0].value?.['noDids']).toEqual(
'test',
)
await upsertOption(
{
scope: 'instance',
key: 'tools.ozone.setting.upsertTest.labelers',
value: { dids: 'test' },
description:
'My personal labelers that i want to use when browsing ozone',
managerRole: 'tools.ozone.team.defs#roleModerator',
},
'moderator',
)
const afterUpdatedByAdmin = await listOptions(
{
scope: 'instance',
prefix: 'tools.ozone.setting.upsertTest.labelers',
},
'admin',
)
expect(afterUpdatedByAdmin.options[0].value?.['noDids']).toBeFalsy()
expect(afterUpdatedByAdmin.options[0].value?.['dids']).toEqual('test')
})
})
describe('listOptions', () => {
beforeAll(async () => {
await upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.client.queues',
value: { stratosphere: { name: 'Stratosphere' } },
description:
'This determines how many queues the client interface will show',
managerRole: 'tools.ozone.team.defs#roleAdmin',
})
await upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.client.queueHash',
value: { val: 10.5 },
description:
'This determines how each queue is balanced when sorted by oldest first',
managerRole: 'tools.ozone.team.defs#roleAdmin',
})
await upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.client.externalLabelers',
value: { dids: ['did:plc:xyz'] },
description:
'List of external labelers that will be plugged into the client views',
managerRole: 'tools.ozone.team.defs#roleAdmin',
})
})
afterAll(async () => {
await removeOptions(
[
'tools.ozone.setting.client.queues',
'tools.ozone.setting.client.queueHash',
'tools.ozone.setting.client.externalLabelers',
],
'instance',
)
})
it('returns all personal settings', async () => {
const result = await listOptions({ prefix: 'tools.ozone.setting.client' })
expect(result.options.length).toBe(3)
expect(forSnapshot(result.options)).toMatchSnapshot()
})
it('allows paginating options', async () => {
const params = { prefix: 'tools.ozone.setting.client', limit: 1 }
const pageOne = await listOptions(params)
const pageTwo = await listOptions({
...params,
cursor: pageOne.cursor,
})
const pageThree = await listOptions({
...params,
cursor: pageTwo.cursor,
})
const pageFour = await listOptions({
...params,
cursor: pageThree.cursor,
})
expect(pageFour.options.length).toBe(0)
expect(pageFour.cursor).toBeUndefined()
})
})
describe('removeOptions', () => {
afterAll(async () => {
await Promise.all([
removeOptions(['tools.ozone.setting.personal.labelers'], 'personal'),
removeOptions(
['tools.ozone.setting.only.mod', 'tools.ozone.setting.only.admin'],
'instance',
),
])
})
it('only allows the owner to delete personal setting', async () => {
await upsertOption({
scope: 'personal',
key: 'tools.ozone.setting.personal.labelers',
value: { dids: ['did:plc:xyz'] },
description:
'My personal labelers that i want to use when browsing ozone',
managerRole: 'tools.ozone.team.defs#roleOwner',
})
// one user can't remove personal setting of another
await removeOptions(
['tools.ozone.setting.personal.labelers'],
'personal',
'triage',
)
const list = await listOptions({ scope: 'personal' }, 'admin')
expect(list.options.length).toBe(1)
// the owner of the personal setting can remove their own setting
await removeOptions(['tools.ozone.setting.personal.labelers'], 'personal')
const listAfterRemoval = await listOptions({ scope: 'personal' }, 'admin')
expect(listAfterRemoval.options.length).toBe(0)
})
it('only allows managerRole to delete instance setting', async () => {
await Promise.all([
upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.only.mod',
value: { dids: ['did:plc:xyz'] },
description: 'Triage mods can not manage these',
managerRole: 'tools.ozone.team.defs#roleModerator',
}),
upsertOption({
scope: 'instance',
key: 'tools.ozone.setting.only.admin',
value: { dids: ['did:plc:xyz'] },
description: 'Moderators or triage mods can not manage these',
managerRole: 'tools.ozone.team.defs#roleAdmin',
}),
])
await Promise.all([
removeOptions(['tools.ozone.setting.only.mod'], 'instance', 'triage'),
removeOptions(
['tools.ozone.setting.only.admin'],
'instance',
'moderator',
),
removeOptions(['tools.ozone.setting.only.admin'], 'instance', 'triage'),
])
const afterFailedAttempt = await listOptions(
{ scope: 'instance', prefix: 'tools.ozone.setting.only' },
'admin',
)
const keysAfterFailedAttempt = afterFailedAttempt.options.map(
(o) => o.key,
)
const keys = [
'tools.ozone.setting.only.mod',
'tools.ozone.setting.only.admin',
]
keys.forEach((key) => expect(keysAfterFailedAttempt).toContain(key))
await Promise.all([
removeOptions(['tools.ozone.setting.only.mod'], 'instance', 'admin'),
removeOptions(['tools.ozone.setting.only.admin'], 'instance', 'admin'),
])
const afterRemoval = await listOptions(
{ scope: 'instance', prefix: 'tools.ozone.setting.only' },
'admin',
)
expect(afterRemoval.options.length).toBe(0)
})
})
})