@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.
@@ -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
- it('upsertMutedWords', async () => {
1773
- await agent.upsertMutedWords(mutedWords)
1774
- await agent.upsertMutedWords(mutedWords) // double
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
- it('upsertMutedWords with #', async () => {
1782
- await agent.upsertMutedWords([
1783
- { value: 'hashtag', targets: ['content'] },
1784
- ])
1785
- // is sanitized to `hashtag`
1786
- await agent.upsertMutedWords([{ value: '#hashtag', targets: ['tag'] }])
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
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
1779
+ const { moderationPrefs } = await agent.getPreferences()
1780
+ const word = moderationPrefs.mutedWords.find(
1781
+ (m) => m.value === 'word',
1782
+ )
1789
1783
 
1790
- expect(mutedWords.find((m) => m.value === '#hashtag')).toBeFalsy()
1791
- // merged with existing
1792
- expect(mutedWords.find((m) => m.value === 'hashtag')).toStrictEqual({
1793
- value: 'hashtag',
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
- it('updateMutedWord', async () => {
1801
- await agent.updateMutedWord({
1802
- value: 'tag_then_content',
1803
- targets: ['content'],
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
- await agent.updateMutedWord({
1806
- value: 'tag_then_both',
1807
- targets: ['content', 'tag'],
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
- expect(
1814
- mutedWords.find((m) => m.value === 'tag_then_content'),
1815
- ).toHaveProperty('targets', ['content'])
1816
- expect(
1817
- mutedWords.find((m) => m.value === 'tag_then_both'),
1818
- ).toHaveProperty('targets', ['content', 'tag'])
1819
- expect(
1820
- mutedWords.find((m) => m.value === 'tag_then_none'),
1821
- ).toHaveProperty('targets', [])
1822
- expect(mutedWords.find((m) => m.value === 'no_exist')).toBeFalsy()
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
- it('updateMutedWord with #, does not update', async () => {
1826
- await agent.upsertMutedWords([
1827
- {
1828
- value: '#just_a_tag',
1829
- targets: ['tag'],
1830
- },
1831
- ])
1832
- await agent.updateMutedWord({
1833
- value: '#just_a_tag',
1834
- targets: ['tag', 'content'],
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
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
1837
- expect(mutedWords.find((m) => m.value === 'just_a_tag')).toStrictEqual({
1838
- value: 'just_a_tag',
1839
- targets: ['tag'],
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
- it('removeMutedWord', async () => {
1844
- await agent.removeMutedWord({ value: 'tag_then_content', targets: [] })
1845
- await agent.removeMutedWord({ value: 'tag_then_both', targets: [] })
1846
- await agent.removeMutedWord({ value: 'tag_then_none', targets: [] })
1847
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- expect(
1850
- mutedWords.find((m) => m.value === 'tag_then_content'),
1851
- ).toBeFalsy()
1852
- expect(mutedWords.find((m) => m.value === 'tag_then_both')).toBeFalsy()
1853
- expect(mutedWords.find((m) => m.value === 'tag_then_none')).toBeFalsy()
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
- it('removeMutedWord with #, no match, no removal', async () => {
1857
- await agent.removeMutedWord({ value: '#hashtag', targets: [] })
1858
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- // was inserted with #hashtag, but we don't sanitize on remove
1861
- expect(mutedWords.find((m) => m.value === 'hashtag')).toBeTruthy()
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
- it('single-hash #', async () => {
1865
- const prev = (await agent.getPreferences()).moderationPrefs
1866
- const length = prev.mutedWords.length
1867
- await agent.upsertMutedWords([{ value: '#', targets: [] }])
1868
- const end = (await agent.getPreferences()).moderationPrefs
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
- // sanitized to empty string, not inserted
1871
- expect(end.mutedWords.length).toEqual(length)
1956
+ expect(moderationPrefs.mutedWords.length).toEqual(3)
1957
+ })
1872
1958
  })
1873
1959
 
1874
- it('multi-hash ##', async () => {
1875
- await agent.upsertMutedWords([{ value: '##', targets: [] }])
1876
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- expect(mutedWords.find((m) => m.value === '#')).toBeTruthy()
1971
+ expect(moderationPrefs.mutedWords.length).toEqual(2)
1972
+ })
1879
1973
  })
1880
1974
 
1881
- it('multi-hash ##hashtag', async () => {
1882
- await agent.upsertMutedWords([{ value: '##hashtag', targets: [] }])
1883
- const a = (await agent.getPreferences()).moderationPrefs
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
- expect(a.mutedWords.find((w) => w.value === '#hashtag')).toBeTruthy()
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
- await agent.removeMutedWord({ value: '#hashtag', targets: [] })
1888
- const b = (await agent.getPreferences()).moderationPrefs
1993
+ const a = await agent.getPreferences()
1994
+ const word = a.moderationPrefs.mutedWords.find(
1995
+ (m) => m.value === 'value',
1996
+ )
1889
1997
 
1890
- expect(b.mutedWords.find((w) => w.value === '#hashtag')).toBeFalsy()
1891
- })
1998
+ await agent.updateMutedWord({
1999
+ ...word!,
2000
+ value: '#new value',
2001
+ })
1892
2002
 
1893
- it('hash emoji #️⃣', async () => {
1894
- await agent.upsertMutedWords([{ value: '#️⃣', targets: [] }])
1895
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
2003
+ const b = await agent.getPreferences()
2004
+ const updatedWord = b.moderationPrefs.mutedWords.find(
2005
+ (m) => m.id === word!.id,
2006
+ )
1896
2007
 
1897
- expect(mutedWords.find((m) => m.value === '#️⃣')).toBeTruthy()
2008
+ expect(updatedWord!.value).toEqual('new value')
2009
+ expect(updatedWord).toHaveProperty('targets', ['content'])
2010
+ })
1898
2011
 
1899
- await agent.removeMutedWord({ value: '#️⃣', targets: [] })
1900
- const end = (await agent.getPreferences()).moderationPrefs
2012
+ it('updates targets', async () => {
2013
+ await agent.addMutedWord({
2014
+ value: 'word',
2015
+ targets: ['tag'],
2016
+ actorTarget: 'all',
2017
+ })
1901
2018
 
1902
- expect(end.mutedWords.find((m) => m.value === '#️⃣')).toBeFalsy()
1903
- })
2019
+ const a = await agent.getPreferences()
2020
+ const word = a.moderationPrefs.mutedWords.find(
2021
+ (m) => m.value === 'word',
2022
+ )
1904
2023
 
1905
- it('hash emoji ##️⃣', async () => {
1906
- await agent.upsertMutedWords([{ value: '##️⃣', targets: [] }])
1907
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
2024
+ await agent.updateMutedWord({
2025
+ ...word!,
2026
+ targets: ['content'],
2027
+ })
1908
2028
 
1909
- expect(mutedWords.find((m) => m.value === '#️⃣')).toBeTruthy()
2029
+ const b = await agent.getPreferences()
1910
2030
 
1911
- await agent.removeMutedWord({ value: '#️⃣', targets: [] })
1912
- const end = (await agent.getPreferences()).moderationPrefs
2031
+ expect(
2032
+ b.moderationPrefs.mutedWords.find((m) => m.id === word!.id),
2033
+ ).toHaveProperty('targets', ['content'])
2034
+ })
1913
2035
 
1914
- expect(end.mutedWords.find((m) => m.value === '#️⃣')).toBeFalsy()
1915
- })
2036
+ it('updates actorTarget', async () => {
2037
+ await agent.addMutedWord({
2038
+ value: 'value',
2039
+ targets: ['content'],
2040
+ actorTarget: 'all',
2041
+ })
1916
2042
 
1917
- it('hash emoji ###️⃣', async () => {
1918
- await agent.upsertMutedWords([{ value: '###️⃣', targets: [] }])
1919
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
2043
+ const a = await agent.getPreferences()
2044
+ const word = a.moderationPrefs.mutedWords.find(
2045
+ (m) => m.value === 'value',
2046
+ )
1920
2047
 
1921
- expect(mutedWords.find((m) => m.value === '##️⃣')).toBeTruthy()
2048
+ await agent.updateMutedWord({
2049
+ ...word!,
2050
+ actorTarget: 'exclude-following',
2051
+ })
1922
2052
 
1923
- await agent.removeMutedWord({ value: '##️⃣', targets: [] })
1924
- const end = (await agent.getPreferences()).moderationPrefs
2053
+ const b = await agent.getPreferences()
1925
2054
 
1926
- expect(end.mutedWords.find((m) => m.value === '##️⃣')).toBeFalsy()
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
- it(`apostrophe: Bluesky's`, async () => {
1930
- await agent.upsertMutedWords([{ value: `Bluesky's`, targets: [] }])
1931
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
2080
+ const b = await agent.getPreferences()
1932
2081
 
1933
- expect(mutedWords.find((m) => m.value === `Bluesky's`)).toBeTruthy()
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(`invalid characters`, () => {
1937
- it('zero width space', async () => {
1938
- const prev = (await agent.getPreferences()).moderationPrefs
1939
- const length = prev.mutedWords.length
1940
- await agent.upsertMutedWords([{ value: '#​', targets: [] }])
1941
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- expect(mutedWords.length).toEqual(length)
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('newline', async () => {
1947
- await agent.upsertMutedWords([
1948
- { value: 'test value\n with newline', targets: [] },
1949
- ])
1950
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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.value === 'test value with newline'),
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: 'test value\n\r with newline', targets: [] },
2263
+ { value: 'word2', targets: ['tag'], actorTarget: 'all' },
1960
2264
  ])
1961
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
1962
2265
 
1963
- expect(
1964
- mutedWords.find((m) => m.value === 'test value with newline'),
1965
- ).toBeTruthy()
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
- it('empty space', async () => {
1969
- await agent.upsertMutedWords([{ value: ' ', targets: [] }])
1970
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- expect(mutedWords.find((m) => m.value === ' ')).toBeFalsy()
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
- it('leading/trailing space', async () => {
1976
- await agent.upsertMutedWords([{ value: ' trim ', targets: [] }])
1977
- const { mutedWords } = (await agent.getPreferences()).moderationPrefs
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
- expect(mutedWords.find((m) => m.value === 'trim')).toBeTruthy()
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
  })