@atproto/api 0.12.25 → 0.12.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/bsky-agent.d.ts +23 -1
- package/dist/bsky-agent.d.ts.map +1 -1
- package/dist/bsky-agent.js +106 -42
- package/dist/bsky-agent.js.map +1 -1
- package/dist/client/lexicons.d.ts +14 -0
- package/dist/client/lexicons.d.ts.map +1 -1
- package/dist/client/lexicons.js +14 -0
- package/dist/client/lexicons.js.map +1 -1
- package/dist/client/types/app/bsky/actor/defs.d.ts +5 -0
- package/dist/client/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/client/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/moderation/mutewords.d.ts +2 -1
- package/dist/moderation/mutewords.d.ts.map +1 -1
- package/dist/moderation/mutewords.js +7 -1
- package/dist/moderation/mutewords.js.map +1 -1
- package/dist/moderation/subjects/post.js +13 -0
- package/dist/moderation/subjects/post.js.map +1 -1
- package/package.json +1 -1
- package/src/bsky-agent.ts +139 -45
- package/src/client/lexicons.ts +16 -0
- package/src/client/types/app/bsky/actor/defs.ts +5 -0
- package/src/moderation/mutewords.ts +11 -0
- package/src/moderation/subjects/post.ts +15 -0
- package/tests/bsky-agent.test.ts +525 -156
- package/tests/moderation-mutewords.test.ts +308 -50
package/tests/bsky-agent.test.ts
CHANGED
|
@@ -1751,14 +1751,6 @@ describe('agent', () => {
|
|
|
1751
1751
|
|
|
1752
1752
|
describe('muted words', () => {
|
|
1753
1753
|
let agent: BskyAgent
|
|
1754
|
-
const mutedWords = [
|
|
1755
|
-
{ value: 'both', targets: ['content', 'tag'] },
|
|
1756
|
-
{ value: 'content', targets: ['content'] },
|
|
1757
|
-
{ value: 'tag', targets: ['tag'] },
|
|
1758
|
-
{ value: 'tag_then_both', targets: ['tag'] },
|
|
1759
|
-
{ value: 'tag_then_content', targets: ['tag'] },
|
|
1760
|
-
{ value: 'tag_then_none', targets: ['tag'] },
|
|
1761
|
-
]
|
|
1762
1754
|
|
|
1763
1755
|
beforeAll(async () => {
|
|
1764
1756
|
agent = new BskyAgent({ service: network.pds.url })
|
|
@@ -1769,214 +1761,591 @@ describe('agent', () => {
|
|
|
1769
1761
|
})
|
|
1770
1762
|
})
|
|
1771
1763
|
|
|
1772
|
-
|
|
1773
|
-
await agent.
|
|
1774
|
-
await agent.
|
|
1775
|
-
await expect(agent.getPreferences()).resolves.toHaveProperty(
|
|
1776
|
-
'moderationPrefs.mutedWords',
|
|
1777
|
-
mutedWords,
|
|
1778
|
-
)
|
|
1764
|
+
afterEach(async () => {
|
|
1765
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1766
|
+
await agent.removeMutedWords(moderationPrefs.mutedWords)
|
|
1779
1767
|
})
|
|
1780
1768
|
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1769
|
+
describe('addMutedWord', () => {
|
|
1770
|
+
it('inserts', async () => {
|
|
1771
|
+
const expiresAt = new Date(Date.now() + 6e3).toISOString()
|
|
1772
|
+
await agent.addMutedWord({
|
|
1773
|
+
value: 'word',
|
|
1774
|
+
targets: ['content'],
|
|
1775
|
+
actorTarget: 'all',
|
|
1776
|
+
expiresAt,
|
|
1777
|
+
})
|
|
1787
1778
|
|
|
1788
|
-
|
|
1779
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1780
|
+
const word = moderationPrefs.mutedWords.find(
|
|
1781
|
+
(m) => m.value === 'word',
|
|
1782
|
+
)
|
|
1789
1783
|
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
targets: ['content', 'tag'],
|
|
1784
|
+
expect(word!.id).toBeTruthy()
|
|
1785
|
+
expect(word!.targets).toEqual(['content'])
|
|
1786
|
+
expect(word!.actorTarget).toEqual('all')
|
|
1787
|
+
expect(word!.expiresAt).toEqual(expiresAt)
|
|
1795
1788
|
})
|
|
1796
|
-
// only one added
|
|
1797
|
-
expect(mutedWords.filter((m) => m.value === 'hashtag').length).toBe(1)
|
|
1798
|
-
})
|
|
1799
1789
|
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1790
|
+
it('single-hash #, no insert', async () => {
|
|
1791
|
+
await agent.addMutedWord({
|
|
1792
|
+
value: '#',
|
|
1793
|
+
targets: [],
|
|
1794
|
+
actorTarget: 'all',
|
|
1795
|
+
})
|
|
1796
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1797
|
+
|
|
1798
|
+
// sanitized to empty string, not inserted
|
|
1799
|
+
expect(moderationPrefs.mutedWords.length).toEqual(0)
|
|
1804
1800
|
})
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1801
|
+
|
|
1802
|
+
it('multi-hash ##, inserts #', async () => {
|
|
1803
|
+
await agent.addMutedWord({
|
|
1804
|
+
value: '##',
|
|
1805
|
+
targets: [],
|
|
1806
|
+
actorTarget: 'all',
|
|
1807
|
+
})
|
|
1808
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1809
|
+
expect(
|
|
1810
|
+
moderationPrefs.mutedWords.find((m) => m.value === '#'),
|
|
1811
|
+
).toBeTruthy()
|
|
1808
1812
|
})
|
|
1809
|
-
await agent.updateMutedWord({ value: 'tag_then_none', targets: [] })
|
|
1810
|
-
await agent.updateMutedWord({ value: 'no_exist', targets: ['tag'] })
|
|
1811
|
-
const { mutedWords } = (await agent.getPreferences()).moderationPrefs
|
|
1812
1813
|
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1814
|
+
it('multi-hash ##hashtag, inserts #hashtag', async () => {
|
|
1815
|
+
await agent.addMutedWord({
|
|
1816
|
+
value: '##hashtag',
|
|
1817
|
+
targets: [],
|
|
1818
|
+
actorTarget: 'all',
|
|
1819
|
+
})
|
|
1820
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1821
|
+
expect(
|
|
1822
|
+
moderationPrefs.mutedWords.find((w) => w.value === '#hashtag'),
|
|
1823
|
+
).toBeTruthy()
|
|
1824
|
+
})
|
|
1824
1825
|
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1826
|
+
it('hash emoji #️⃣, inserts #️⃣', async () => {
|
|
1827
|
+
await agent.addMutedWord({
|
|
1828
|
+
value: '#️⃣',
|
|
1829
|
+
targets: [],
|
|
1830
|
+
actorTarget: 'all',
|
|
1831
|
+
})
|
|
1832
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1833
|
+
expect(
|
|
1834
|
+
moderationPrefs.mutedWords.find((m) => m.value === '#️⃣'),
|
|
1835
|
+
).toBeTruthy()
|
|
1835
1836
|
})
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1837
|
+
|
|
1838
|
+
it('hash emoji w/leading hash ##️⃣, inserts #️⃣', async () => {
|
|
1839
|
+
await agent.addMutedWord({
|
|
1840
|
+
value: '##️⃣',
|
|
1841
|
+
targets: [],
|
|
1842
|
+
actorTarget: 'all',
|
|
1843
|
+
})
|
|
1844
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1845
|
+
expect(
|
|
1846
|
+
moderationPrefs.mutedWords.find((m) => m.value === '#️⃣'),
|
|
1847
|
+
).toBeTruthy()
|
|
1840
1848
|
})
|
|
1841
|
-
})
|
|
1842
1849
|
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1850
|
+
it('hash emoji with double leading hash ###️⃣, inserts ##️⃣', async () => {
|
|
1851
|
+
await agent.addMutedWord({
|
|
1852
|
+
value: '###️⃣',
|
|
1853
|
+
targets: [],
|
|
1854
|
+
actorTarget: 'all',
|
|
1855
|
+
})
|
|
1856
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1857
|
+
expect(
|
|
1858
|
+
moderationPrefs.mutedWords.find((m) => m.value === '##️⃣'),
|
|
1859
|
+
).toBeTruthy()
|
|
1860
|
+
})
|
|
1848
1861
|
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1862
|
+
it(`includes apostrophes e.g. Bluesky's`, async () => {
|
|
1863
|
+
await agent.addMutedWord({
|
|
1864
|
+
value: `Bluesky's`,
|
|
1865
|
+
targets: [],
|
|
1866
|
+
actorTarget: 'all',
|
|
1867
|
+
})
|
|
1868
|
+
const { mutedWords } = (await agent.getPreferences()).moderationPrefs
|
|
1869
|
+
|
|
1870
|
+
expect(mutedWords.find((m) => m.value === `Bluesky's`)).toBeTruthy()
|
|
1871
|
+
})
|
|
1855
1872
|
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1873
|
+
describe(`invalid characters`, () => {
|
|
1874
|
+
it('#<zws>, no insert', async () => {
|
|
1875
|
+
await agent.addMutedWord({
|
|
1876
|
+
value: '#',
|
|
1877
|
+
targets: [],
|
|
1878
|
+
actorTarget: 'all',
|
|
1879
|
+
})
|
|
1880
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1881
|
+
expect(moderationPrefs.mutedWords.length).toEqual(0)
|
|
1882
|
+
})
|
|
1859
1883
|
|
|
1860
|
-
|
|
1861
|
-
|
|
1884
|
+
it('#<zws>ab, inserts ab', async () => {
|
|
1885
|
+
await agent.addMutedWord({
|
|
1886
|
+
value: '#ab',
|
|
1887
|
+
targets: [],
|
|
1888
|
+
actorTarget: 'all',
|
|
1889
|
+
})
|
|
1890
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1891
|
+
expect(moderationPrefs.mutedWords.length).toEqual(1)
|
|
1892
|
+
})
|
|
1893
|
+
|
|
1894
|
+
it('phrase with newline, inserts phrase without newline', async () => {
|
|
1895
|
+
await agent.addMutedWord({
|
|
1896
|
+
value: 'test value\n with newline',
|
|
1897
|
+
targets: [],
|
|
1898
|
+
actorTarget: 'all',
|
|
1899
|
+
})
|
|
1900
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1901
|
+
expect(
|
|
1902
|
+
moderationPrefs.mutedWords.find(
|
|
1903
|
+
(m) => m.value === 'test value with newline',
|
|
1904
|
+
),
|
|
1905
|
+
).toBeTruthy()
|
|
1906
|
+
})
|
|
1907
|
+
|
|
1908
|
+
it('phrase with newlines, inserts phrase without newlines', async () => {
|
|
1909
|
+
await agent.addMutedWord({
|
|
1910
|
+
value: 'test value\n\r with newline',
|
|
1911
|
+
targets: [],
|
|
1912
|
+
actorTarget: 'all',
|
|
1913
|
+
})
|
|
1914
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1915
|
+
expect(
|
|
1916
|
+
moderationPrefs.mutedWords.find(
|
|
1917
|
+
(m) => m.value === 'test value with newline',
|
|
1918
|
+
),
|
|
1919
|
+
).toBeTruthy()
|
|
1920
|
+
})
|
|
1921
|
+
|
|
1922
|
+
it('empty space, no insert', async () => {
|
|
1923
|
+
await agent.addMutedWord({
|
|
1924
|
+
value: ' ',
|
|
1925
|
+
targets: [],
|
|
1926
|
+
actorTarget: 'all',
|
|
1927
|
+
})
|
|
1928
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1929
|
+
expect(moderationPrefs.mutedWords.length).toEqual(0)
|
|
1930
|
+
})
|
|
1931
|
+
|
|
1932
|
+
it(`' trim ', inserts 'trim'`, async () => {
|
|
1933
|
+
await agent.addMutedWord({
|
|
1934
|
+
value: ' trim ',
|
|
1935
|
+
targets: [],
|
|
1936
|
+
actorTarget: 'all',
|
|
1937
|
+
})
|
|
1938
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1939
|
+
expect(
|
|
1940
|
+
moderationPrefs.mutedWords.find((m) => m.value === 'trim'),
|
|
1941
|
+
).toBeTruthy()
|
|
1942
|
+
})
|
|
1943
|
+
})
|
|
1862
1944
|
})
|
|
1863
1945
|
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1946
|
+
describe('addMutedWords', () => {
|
|
1947
|
+
it('inserts happen sequentially, no clobbering', async () => {
|
|
1948
|
+
await agent.addMutedWords([
|
|
1949
|
+
{ value: 'a', targets: ['content'], actorTarget: 'all' },
|
|
1950
|
+
{ value: 'b', targets: ['content'], actorTarget: 'all' },
|
|
1951
|
+
{ value: 'c', targets: ['content'], actorTarget: 'all' },
|
|
1952
|
+
])
|
|
1953
|
+
|
|
1954
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1869
1955
|
|
|
1870
|
-
|
|
1871
|
-
|
|
1956
|
+
expect(moderationPrefs.mutedWords.length).toEqual(3)
|
|
1957
|
+
})
|
|
1872
1958
|
})
|
|
1873
1959
|
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1960
|
+
describe('upsertMutedWords (deprecated)', () => {
|
|
1961
|
+
it('no longer upserts, calls addMutedWords', async () => {
|
|
1962
|
+
await agent.upsertMutedWords([
|
|
1963
|
+
{ value: 'both', targets: ['content'], actorTarget: 'all' },
|
|
1964
|
+
])
|
|
1965
|
+
await agent.upsertMutedWords([
|
|
1966
|
+
{ value: 'both', targets: ['tag'], actorTarget: 'all' },
|
|
1967
|
+
])
|
|
1968
|
+
|
|
1969
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1877
1970
|
|
|
1878
|
-
|
|
1971
|
+
expect(moderationPrefs.mutedWords.length).toEqual(2)
|
|
1972
|
+
})
|
|
1879
1973
|
})
|
|
1880
1974
|
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1975
|
+
describe('updateMutedWord', () => {
|
|
1976
|
+
it(`word doesn't exist, no update or insert`, async () => {
|
|
1977
|
+
await agent.updateMutedWord({
|
|
1978
|
+
value: 'word',
|
|
1979
|
+
targets: ['tag', 'content'],
|
|
1980
|
+
actorTarget: 'all',
|
|
1981
|
+
})
|
|
1982
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
1983
|
+
expect(moderationPrefs.mutedWords.length).toEqual(0)
|
|
1984
|
+
})
|
|
1884
1985
|
|
|
1885
|
-
|
|
1986
|
+
it('updates and sanitizes new value', async () => {
|
|
1987
|
+
await agent.addMutedWord({
|
|
1988
|
+
value: 'value',
|
|
1989
|
+
targets: ['content'],
|
|
1990
|
+
actorTarget: 'all',
|
|
1991
|
+
})
|
|
1886
1992
|
|
|
1887
|
-
|
|
1888
|
-
|
|
1993
|
+
const a = await agent.getPreferences()
|
|
1994
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
1995
|
+
(m) => m.value === 'value',
|
|
1996
|
+
)
|
|
1889
1997
|
|
|
1890
|
-
|
|
1891
|
-
|
|
1998
|
+
await agent.updateMutedWord({
|
|
1999
|
+
...word!,
|
|
2000
|
+
value: '#new value',
|
|
2001
|
+
})
|
|
1892
2002
|
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2003
|
+
const b = await agent.getPreferences()
|
|
2004
|
+
const updatedWord = b.moderationPrefs.mutedWords.find(
|
|
2005
|
+
(m) => m.id === word!.id,
|
|
2006
|
+
)
|
|
1896
2007
|
|
|
1897
|
-
|
|
2008
|
+
expect(updatedWord!.value).toEqual('new value')
|
|
2009
|
+
expect(updatedWord).toHaveProperty('targets', ['content'])
|
|
2010
|
+
})
|
|
1898
2011
|
|
|
1899
|
-
|
|
1900
|
-
|
|
2012
|
+
it('updates targets', async () => {
|
|
2013
|
+
await agent.addMutedWord({
|
|
2014
|
+
value: 'word',
|
|
2015
|
+
targets: ['tag'],
|
|
2016
|
+
actorTarget: 'all',
|
|
2017
|
+
})
|
|
1901
2018
|
|
|
1902
|
-
|
|
1903
|
-
|
|
2019
|
+
const a = await agent.getPreferences()
|
|
2020
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2021
|
+
(m) => m.value === 'word',
|
|
2022
|
+
)
|
|
1904
2023
|
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
2024
|
+
await agent.updateMutedWord({
|
|
2025
|
+
...word!,
|
|
2026
|
+
targets: ['content'],
|
|
2027
|
+
})
|
|
1908
2028
|
|
|
1909
|
-
|
|
2029
|
+
const b = await agent.getPreferences()
|
|
1910
2030
|
|
|
1911
|
-
|
|
1912
|
-
|
|
2031
|
+
expect(
|
|
2032
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
2033
|
+
).toHaveProperty('targets', ['content'])
|
|
2034
|
+
})
|
|
1913
2035
|
|
|
1914
|
-
|
|
1915
|
-
|
|
2036
|
+
it('updates actorTarget', async () => {
|
|
2037
|
+
await agent.addMutedWord({
|
|
2038
|
+
value: 'value',
|
|
2039
|
+
targets: ['content'],
|
|
2040
|
+
actorTarget: 'all',
|
|
2041
|
+
})
|
|
1916
2042
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
2043
|
+
const a = await agent.getPreferences()
|
|
2044
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2045
|
+
(m) => m.value === 'value',
|
|
2046
|
+
)
|
|
1920
2047
|
|
|
1921
|
-
|
|
2048
|
+
await agent.updateMutedWord({
|
|
2049
|
+
...word!,
|
|
2050
|
+
actorTarget: 'exclude-following',
|
|
2051
|
+
})
|
|
1922
2052
|
|
|
1923
|
-
|
|
1924
|
-
const end = (await agent.getPreferences()).moderationPrefs
|
|
2053
|
+
const b = await agent.getPreferences()
|
|
1925
2054
|
|
|
1926
|
-
|
|
1927
|
-
|
|
2055
|
+
expect(
|
|
2056
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
2057
|
+
).toHaveProperty('actorTarget', 'exclude-following')
|
|
2058
|
+
})
|
|
2059
|
+
|
|
2060
|
+
it('updates expiresAt', async () => {
|
|
2061
|
+
const expiresAt = new Date(Date.now() + 6e3).toISOString()
|
|
2062
|
+
const expiresAt2 = new Date(Date.now() + 10e3).toISOString()
|
|
2063
|
+
await agent.addMutedWord({
|
|
2064
|
+
value: 'value',
|
|
2065
|
+
targets: ['content'],
|
|
2066
|
+
expiresAt,
|
|
2067
|
+
actorTarget: 'all',
|
|
2068
|
+
})
|
|
2069
|
+
|
|
2070
|
+
const a = await agent.getPreferences()
|
|
2071
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2072
|
+
(m) => m.value === 'value',
|
|
2073
|
+
)
|
|
2074
|
+
|
|
2075
|
+
await agent.updateMutedWord({
|
|
2076
|
+
...word!,
|
|
2077
|
+
expiresAt: expiresAt2,
|
|
2078
|
+
})
|
|
1928
2079
|
|
|
1929
|
-
|
|
1930
|
-
await agent.upsertMutedWords([{ value: `Bluesky's`, targets: [] }])
|
|
1931
|
-
const { mutedWords } = (await agent.getPreferences()).moderationPrefs
|
|
2080
|
+
const b = await agent.getPreferences()
|
|
1932
2081
|
|
|
1933
|
-
|
|
2082
|
+
expect(
|
|
2083
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
2084
|
+
).toHaveProperty('expiresAt', expiresAt2)
|
|
2085
|
+
})
|
|
2086
|
+
|
|
2087
|
+
it(`doesn't update if value is sanitized to be falsy`, async () => {
|
|
2088
|
+
await agent.addMutedWord({
|
|
2089
|
+
value: 'rug',
|
|
2090
|
+
targets: ['content'],
|
|
2091
|
+
actorTarget: 'all',
|
|
2092
|
+
})
|
|
2093
|
+
|
|
2094
|
+
const a = await agent.getPreferences()
|
|
2095
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2096
|
+
(m) => m.value === 'rug',
|
|
2097
|
+
)
|
|
2098
|
+
|
|
2099
|
+
await agent.updateMutedWord({
|
|
2100
|
+
...word!,
|
|
2101
|
+
value: '',
|
|
2102
|
+
})
|
|
2103
|
+
|
|
2104
|
+
const b = await agent.getPreferences()
|
|
2105
|
+
|
|
2106
|
+
expect(
|
|
2107
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
2108
|
+
).toHaveProperty('value', 'rug')
|
|
2109
|
+
})
|
|
1934
2110
|
})
|
|
1935
2111
|
|
|
1936
|
-
describe(
|
|
1937
|
-
it('
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
2112
|
+
describe('removeMutedWord', () => {
|
|
2113
|
+
it('removes word', async () => {
|
|
2114
|
+
await agent.addMutedWord({
|
|
2115
|
+
value: 'word',
|
|
2116
|
+
targets: ['tag'],
|
|
2117
|
+
actorTarget: 'all',
|
|
2118
|
+
})
|
|
2119
|
+
const a = await agent.getPreferences()
|
|
2120
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2121
|
+
(m) => m.value === 'word',
|
|
2122
|
+
)
|
|
2123
|
+
|
|
2124
|
+
await agent.removeMutedWord(word!)
|
|
1942
2125
|
|
|
1943
|
-
|
|
2126
|
+
const b = await agent.getPreferences()
|
|
2127
|
+
|
|
2128
|
+
expect(
|
|
2129
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
2130
|
+
).toBeFalsy()
|
|
1944
2131
|
})
|
|
1945
2132
|
|
|
1946
|
-
it('
|
|
1947
|
-
await agent.
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
2133
|
+
it(`word doesn't exist, no action`, async () => {
|
|
2134
|
+
await agent.addMutedWord({
|
|
2135
|
+
value: 'word',
|
|
2136
|
+
targets: ['tag'],
|
|
2137
|
+
actorTarget: 'all',
|
|
2138
|
+
})
|
|
2139
|
+
const a = await agent.getPreferences()
|
|
2140
|
+
const word = a.moderationPrefs.mutedWords.find(
|
|
2141
|
+
(m) => m.value === 'word',
|
|
2142
|
+
)
|
|
2143
|
+
|
|
2144
|
+
await agent.removeMutedWord({
|
|
2145
|
+
value: 'another',
|
|
2146
|
+
targets: [],
|
|
2147
|
+
actorTarget: 'all',
|
|
2148
|
+
})
|
|
2149
|
+
|
|
2150
|
+
const b = await agent.getPreferences()
|
|
1951
2151
|
|
|
1952
2152
|
expect(
|
|
1953
|
-
mutedWords.find((m) => m.
|
|
2153
|
+
b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
|
|
1954
2154
|
).toBeTruthy()
|
|
1955
2155
|
})
|
|
2156
|
+
})
|
|
2157
|
+
|
|
2158
|
+
describe('removeMutedWords', () => {
|
|
2159
|
+
it(`removes sequentially, no clobbering`, async () => {
|
|
2160
|
+
await agent.addMutedWords([
|
|
2161
|
+
{ value: 'a', targets: ['content'], actorTarget: 'all ' },
|
|
2162
|
+
{ value: 'b', targets: ['content'], actorTarget: 'all ' },
|
|
2163
|
+
{ value: 'c', targets: ['content'], actorTarget: 'all ' },
|
|
2164
|
+
])
|
|
2165
|
+
|
|
2166
|
+
const a = await agent.getPreferences()
|
|
2167
|
+
await agent.removeMutedWords(a.moderationPrefs.mutedWords)
|
|
2168
|
+
const b = await agent.getPreferences()
|
|
2169
|
+
|
|
2170
|
+
expect(b.moderationPrefs.mutedWords.length).toEqual(0)
|
|
2171
|
+
})
|
|
2172
|
+
})
|
|
2173
|
+
})
|
|
2174
|
+
|
|
2175
|
+
describe('legacy muted words', () => {
|
|
2176
|
+
let agent: BskyAgent
|
|
2177
|
+
|
|
2178
|
+
async function updatePreferences(
|
|
2179
|
+
agent: BskyAgent,
|
|
2180
|
+
cb: (
|
|
2181
|
+
prefs: AppBskyActorDefs.Preferences,
|
|
2182
|
+
) => AppBskyActorDefs.Preferences | false,
|
|
2183
|
+
) {
|
|
2184
|
+
const res = await agent.app.bsky.actor.getPreferences({})
|
|
2185
|
+
const newPrefs = cb(res.data.preferences)
|
|
2186
|
+
if (newPrefs === false) {
|
|
2187
|
+
return
|
|
2188
|
+
}
|
|
2189
|
+
await agent.app.bsky.actor.putPreferences({
|
|
2190
|
+
preferences: newPrefs,
|
|
2191
|
+
})
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
async function addLegacyMutedWord(mutedWord: AppBskyActorDefs.MutedWord) {
|
|
2195
|
+
await updatePreferences(agent, (prefs) => {
|
|
2196
|
+
let mutedWordsPref = prefs.findLast(
|
|
2197
|
+
(pref) =>
|
|
2198
|
+
AppBskyActorDefs.isMutedWordsPref(pref) &&
|
|
2199
|
+
AppBskyActorDefs.validateMutedWordsPref(pref).success,
|
|
2200
|
+
)
|
|
2201
|
+
|
|
2202
|
+
const newMutedWord: AppBskyActorDefs.MutedWord = {
|
|
2203
|
+
value: mutedWord.value,
|
|
2204
|
+
targets: mutedWord.targets,
|
|
2205
|
+
actorTarget: 'all',
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
if (
|
|
2209
|
+
mutedWordsPref &&
|
|
2210
|
+
AppBskyActorDefs.isMutedWordsPref(mutedWordsPref)
|
|
2211
|
+
) {
|
|
2212
|
+
mutedWordsPref.items.push(newMutedWord)
|
|
2213
|
+
} else {
|
|
2214
|
+
// if the pref doesn't exist, create it
|
|
2215
|
+
mutedWordsPref = {
|
|
2216
|
+
items: [newMutedWord],
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
return prefs
|
|
2221
|
+
.filter((p) => !AppBskyActorDefs.isMutedWordsPref(p))
|
|
2222
|
+
.concat([
|
|
2223
|
+
{
|
|
2224
|
+
...mutedWordsPref,
|
|
2225
|
+
$type: 'app.bsky.actor.defs#mutedWordsPref',
|
|
2226
|
+
},
|
|
2227
|
+
])
|
|
2228
|
+
})
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
beforeAll(async () => {
|
|
2232
|
+
agent = new BskyAgent({ service: network.pds.url })
|
|
2233
|
+
await agent.createAccount({
|
|
2234
|
+
handle: 'user7-1.test',
|
|
2235
|
+
email: 'user7-1@test.com',
|
|
2236
|
+
password: 'password',
|
|
2237
|
+
})
|
|
2238
|
+
})
|
|
2239
|
+
|
|
2240
|
+
afterEach(async () => {
|
|
2241
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
2242
|
+
await agent.removeMutedWords(moderationPrefs.mutedWords)
|
|
2243
|
+
})
|
|
2244
|
+
|
|
2245
|
+
describe(`upsertMutedWords (and addMutedWord)`, () => {
|
|
2246
|
+
it(`adds new word, migrates old words`, async () => {
|
|
2247
|
+
await addLegacyMutedWord({
|
|
2248
|
+
value: 'word',
|
|
2249
|
+
targets: ['content'],
|
|
2250
|
+
actorTarget: 'all',
|
|
2251
|
+
})
|
|
2252
|
+
|
|
2253
|
+
{
|
|
2254
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
2255
|
+
const word = moderationPrefs.mutedWords.find(
|
|
2256
|
+
(w) => w.value === 'word',
|
|
2257
|
+
)
|
|
2258
|
+
expect(word).toBeTruthy()
|
|
2259
|
+
expect(word!.id).toBeFalsy()
|
|
2260
|
+
}
|
|
1956
2261
|
|
|
1957
|
-
it('newline(s)', async () => {
|
|
1958
2262
|
await agent.upsertMutedWords([
|
|
1959
|
-
{ value: '
|
|
2263
|
+
{ value: 'word2', targets: ['tag'], actorTarget: 'all' },
|
|
1960
2264
|
])
|
|
1961
|
-
const { mutedWords } = (await agent.getPreferences()).moderationPrefs
|
|
1962
2265
|
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2266
|
+
{
|
|
2267
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
2268
|
+
const word = moderationPrefs.mutedWords.find(
|
|
2269
|
+
(w) => w.value === 'word',
|
|
2270
|
+
)
|
|
2271
|
+
const word2 = moderationPrefs.mutedWords.find(
|
|
2272
|
+
(w) => w.value === 'word2',
|
|
2273
|
+
)
|
|
2274
|
+
|
|
2275
|
+
expect(word!.id).toBeTruthy()
|
|
2276
|
+
expect(word2!.id).toBeTruthy()
|
|
2277
|
+
}
|
|
1966
2278
|
})
|
|
2279
|
+
})
|
|
1967
2280
|
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2281
|
+
describe(`updateMutedWord`, () => {
|
|
2282
|
+
it(`updates legacy word, migrates old words`, async () => {
|
|
2283
|
+
await addLegacyMutedWord({
|
|
2284
|
+
value: 'word',
|
|
2285
|
+
targets: ['content'],
|
|
2286
|
+
actorTarget: 'all',
|
|
2287
|
+
})
|
|
2288
|
+
await addLegacyMutedWord({
|
|
2289
|
+
value: 'word2',
|
|
2290
|
+
targets: ['tag'],
|
|
2291
|
+
actorTarget: 'all',
|
|
2292
|
+
})
|
|
1971
2293
|
|
|
1972
|
-
|
|
2294
|
+
await agent.updateMutedWord({
|
|
2295
|
+
value: 'word',
|
|
2296
|
+
targets: ['tag'],
|
|
2297
|
+
actorTarget: 'all',
|
|
2298
|
+
})
|
|
2299
|
+
|
|
2300
|
+
{
|
|
2301
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
2302
|
+
const word = moderationPrefs.mutedWords.find(
|
|
2303
|
+
(w) => w.value === 'word',
|
|
2304
|
+
)
|
|
2305
|
+
const word2 = moderationPrefs.mutedWords.find(
|
|
2306
|
+
(w) => w.value === 'word2',
|
|
2307
|
+
)
|
|
2308
|
+
|
|
2309
|
+
expect(moderationPrefs.mutedWords.length).toEqual(2)
|
|
2310
|
+
expect(word!.id).toBeTruthy()
|
|
2311
|
+
expect(word!.targets).toEqual(['tag'])
|
|
2312
|
+
expect(word2!.id).toBeTruthy()
|
|
2313
|
+
}
|
|
1973
2314
|
})
|
|
2315
|
+
})
|
|
1974
2316
|
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2317
|
+
describe(`removeMutedWord`, () => {
|
|
2318
|
+
it(`removes legacy word, migrates old words`, async () => {
|
|
2319
|
+
await addLegacyMutedWord({
|
|
2320
|
+
value: 'word',
|
|
2321
|
+
targets: ['content'],
|
|
2322
|
+
actorTarget: 'all',
|
|
2323
|
+
})
|
|
2324
|
+
await addLegacyMutedWord({
|
|
2325
|
+
value: 'word2',
|
|
2326
|
+
targets: ['tag'],
|
|
2327
|
+
actorTarget: 'all',
|
|
2328
|
+
})
|
|
2329
|
+
|
|
2330
|
+
await agent.removeMutedWord({
|
|
2331
|
+
value: 'word',
|
|
2332
|
+
targets: ['tag'],
|
|
2333
|
+
actorTarget: 'all',
|
|
2334
|
+
})
|
|
1978
2335
|
|
|
1979
|
-
|
|
2336
|
+
{
|
|
2337
|
+
const { moderationPrefs } = await agent.getPreferences()
|
|
2338
|
+
const word = moderationPrefs.mutedWords.find(
|
|
2339
|
+
(w) => w.value === 'word',
|
|
2340
|
+
)
|
|
2341
|
+
const word2 = moderationPrefs.mutedWords.find(
|
|
2342
|
+
(w) => w.value === 'word2',
|
|
2343
|
+
)
|
|
2344
|
+
|
|
2345
|
+
expect(moderationPrefs.mutedWords.length).toEqual(1)
|
|
2346
|
+
expect(word).toBeFalsy()
|
|
2347
|
+
expect(word2!.id).toBeTruthy()
|
|
2348
|
+
}
|
|
1980
2349
|
})
|
|
1981
2350
|
})
|
|
1982
2351
|
})
|