atproto/packages/api/tests/moderation-prefs.test.ts
dan a3ce23c4cc
Add hotness as a default thread sort option (#3082)
* Add hotness as a thread sorting option

* Changeset
2024-11-22 18:36:55 -08:00

362 lines
10 KiB
TypeScript

import { TestNetworkNoAppView } from '@atproto/dev-env'
import { DEFAULT_LABEL_SETTINGS } from '../src'
import './util/moderation-behavior'
describe('agent', () => {
let network: TestNetworkNoAppView
beforeAll(async () => {
network = await TestNetworkNoAppView.create({
dbPostgresSchema: 'api_moderation_prefs',
})
})
afterAll(async () => {
await network.close()
})
it('migrates legacy content-label prefs (no mutations)', async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user1.test',
email: 'user1@test.com',
password: 'password',
})
await agent.app.bsky.actor.putPreferences({
preferences: [
{
$type: 'app.bsky.actor.defs#contentLabelPref',
label: 'porn',
visibility: 'show',
},
{
$type: 'app.bsky.actor.defs#contentLabelPref',
label: 'nudity',
visibility: 'show',
},
{
$type: 'app.bsky.actor.defs#contentLabelPref',
label: 'sexual',
visibility: 'show',
},
{
$type: 'app.bsky.actor.defs#contentLabelPref',
label: 'graphic-media',
visibility: 'show',
},
],
})
await expect(agent.getPreferences()).resolves.toStrictEqual({
feeds: {
pinned: undefined,
saved: undefined,
},
savedFeeds: expect.any(Array),
interests: { tags: [] },
moderationPrefs: {
adultContentEnabled: false,
labels: {
porn: 'ignore',
nudity: 'ignore',
sexual: 'ignore',
'graphic-media': 'ignore',
},
labelers: [...agent.appLabelers.map((did) => ({ did, labels: {} }))],
hiddenPosts: [],
mutedWords: [],
},
birthDate: undefined,
feedViewPrefs: {
home: {
hideQuotePosts: false,
hideReplies: false,
hideRepliesByLikeCount: 0,
hideRepliesByUnfollowed: true,
hideReposts: false,
},
},
threadViewPrefs: {
prioritizeFollowedUsers: true,
sort: 'hotness',
},
bskyAppState: {
activeProgressGuide: undefined,
queuedNudges: [],
nuxs: [],
},
})
})
it('adds/removes moderation services', async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user5.test',
email: 'user5@test.com',
password: 'password',
})
await agent.addLabeler('did:plc:other')
expect(agent.labelers).toStrictEqual(['did:plc:other'])
await expect(agent.getPreferences()).resolves.toStrictEqual({
feeds: { pinned: undefined, saved: undefined },
savedFeeds: expect.any(Array),
interests: { tags: [] },
moderationPrefs: {
adultContentEnabled: false,
labels: DEFAULT_LABEL_SETTINGS,
labelers: [
...agent.appLabelers.map((did) => ({ did, labels: {} })),
{
did: 'did:plc:other',
labels: {},
},
],
hiddenPosts: [],
mutedWords: [],
},
birthDate: undefined,
feedViewPrefs: {
home: {
hideReplies: false,
hideRepliesByUnfollowed: true,
hideRepliesByLikeCount: 0,
hideReposts: false,
hideQuotePosts: false,
},
},
threadViewPrefs: {
sort: 'hotness',
prioritizeFollowedUsers: true,
},
bskyAppState: {
activeProgressGuide: undefined,
queuedNudges: [],
nuxs: [],
},
})
expect(agent.labelers).toStrictEqual(['did:plc:other'])
await agent.removeLabeler('did:plc:other')
expect(agent.labelers).toStrictEqual([])
await expect(agent.getPreferences()).resolves.toStrictEqual({
feeds: { pinned: undefined, saved: undefined },
savedFeeds: expect.any(Array),
interests: { tags: [] },
moderationPrefs: {
adultContentEnabled: false,
labels: DEFAULT_LABEL_SETTINGS,
labelers: [...agent.appLabelers.map((did) => ({ did, labels: {} }))],
hiddenPosts: [],
mutedWords: [],
},
birthDate: undefined,
feedViewPrefs: {
home: {
hideReplies: false,
hideRepliesByUnfollowed: true,
hideRepliesByLikeCount: 0,
hideReposts: false,
hideQuotePosts: false,
},
},
threadViewPrefs: {
sort: 'hotness',
prioritizeFollowedUsers: true,
},
bskyAppState: {
activeProgressGuide: undefined,
queuedNudges: [],
nuxs: [],
},
})
expect(agent.labelers).toStrictEqual([])
})
it('sets label preferences globally and per-moderator', async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user7.test',
email: 'user7@test.com',
password: 'password',
})
await agent.addLabeler('did:plc:other')
await agent.setContentLabelPref('porn', 'ignore')
await agent.setContentLabelPref('porn', 'hide', 'did:plc:other')
await agent.setContentLabelPref('x-custom', 'warn', 'did:plc:other')
await expect(agent.getPreferences()).resolves.toStrictEqual({
feeds: { pinned: undefined, saved: undefined },
savedFeeds: expect.any(Array),
interests: { tags: [] },
moderationPrefs: {
adultContentEnabled: false,
labels: { ...DEFAULT_LABEL_SETTINGS, porn: 'ignore', nsfw: 'ignore' },
labelers: [
...agent.appLabelers.map((did) => ({ did, labels: {} })),
{
did: 'did:plc:other',
labels: {
porn: 'hide',
'x-custom': 'warn',
},
},
],
hiddenPosts: [],
mutedWords: [],
},
birthDate: undefined,
feedViewPrefs: {
home: {
hideReplies: false,
hideRepliesByUnfollowed: true,
hideRepliesByLikeCount: 0,
hideReposts: false,
hideQuotePosts: false,
},
},
threadViewPrefs: {
sort: 'hotness',
prioritizeFollowedUsers: true,
},
bskyAppState: {
activeProgressGuide: undefined,
queuedNudges: [],
nuxs: [],
},
})
})
it(`updates label pref`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user8.test',
email: 'user8@test.com',
password: 'password',
})
await agent.addLabeler('did:plc:other')
await agent.setContentLabelPref('porn', 'ignore')
await agent.setContentLabelPref('porn', 'ignore', 'did:plc:other')
await agent.setContentLabelPref('porn', 'hide')
await agent.setContentLabelPref('porn', 'hide', 'did:plc:other')
const { moderationPrefs } = await agent.getPreferences()
const labeler = moderationPrefs.labelers.find(
(l) => l.did === 'did:plc:other',
)
expect(moderationPrefs.labels.porn).toEqual('hide')
expect(labeler?.labels?.porn).toEqual('hide')
})
it(`double-write for legacy: 'graphic-media' in sync with 'gore'`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user9.test',
email: 'user9@test.com',
password: 'password',
})
await agent.setContentLabelPref('graphic-media', 'hide')
const a = await agent.getPreferences()
expect(a.moderationPrefs.labels.gore).toEqual('hide')
expect(a.moderationPrefs.labels['graphic-media']).toEqual('hide')
await agent.setContentLabelPref('graphic-media', 'warn')
const b = await agent.getPreferences()
expect(b.moderationPrefs.labels.gore).toEqual('warn')
expect(b.moderationPrefs.labels['graphic-media']).toEqual('warn')
})
it(`double-write for legacy: 'porn' in sync with 'nsfw'`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user10.test',
email: 'user10@test.com',
password: 'password',
})
await agent.setContentLabelPref('porn', 'hide')
const a = await agent.getPreferences()
expect(a.moderationPrefs.labels.nsfw).toEqual('hide')
expect(a.moderationPrefs.labels.porn).toEqual('hide')
await agent.setContentLabelPref('porn', 'warn')
const b = await agent.getPreferences()
expect(b.moderationPrefs.labels.nsfw).toEqual('warn')
expect(b.moderationPrefs.labels.porn).toEqual('warn')
})
it(`double-write for legacy: 'sexual' in sync with 'suggestive'`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user11.test',
email: 'user11@test.com',
password: 'password',
})
await agent.setContentLabelPref('sexual', 'hide')
const a = await agent.getPreferences()
expect(a.moderationPrefs.labels.sexual).toEqual('hide')
expect(a.moderationPrefs.labels.suggestive).toEqual('hide')
await agent.setContentLabelPref('sexual', 'warn')
const b = await agent.getPreferences()
expect(b.moderationPrefs.labels.sexual).toEqual('warn')
expect(b.moderationPrefs.labels.suggestive).toEqual('warn')
})
it(`double-write for legacy: filters out existing old label pref if double-written`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user12.test',
email: 'user12@test.com',
password: 'password',
})
await agent.setContentLabelPref('nsfw', 'hide')
await agent.setContentLabelPref('porn', 'hide')
const a = await agent.app.bsky.actor.getPreferences({})
const nsfwSettings = a.data.preferences.filter(
(pref) => pref.label === 'nsfw',
)
expect(nsfwSettings.length).toEqual(1)
})
it(`remaps old values to new on read`, async () => {
const agent = network.pds.getClient()
await agent.createAccount({
handle: 'user13.test',
email: 'user13@test.com',
password: 'password',
})
await agent.setContentLabelPref('nsfw', 'hide')
await agent.setContentLabelPref('gore', 'hide')
await agent.setContentLabelPref('suggestive', 'hide')
const a = await agent.getPreferences()
expect(a.moderationPrefs.labels.porn).toEqual('hide')
expect(a.moderationPrefs.labels['graphic-media']).toEqual('hide')
expect(a.moderationPrefs.labels['sexual']).toEqual('hide')
})
})