Track starter pack opt-out actions
This commit is contained in:
@@ -715,6 +715,10 @@ export type Events = {
|
|||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
'starterPack:delete': {}
|
'starterPack:delete': {}
|
||||||
|
'starterPack:optOut': {
|
||||||
|
starterPack: string
|
||||||
|
action: 'optOut' | 'undo'
|
||||||
|
}
|
||||||
'starterPack:create': {
|
'starterPack:create': {
|
||||||
setName: boolean
|
setName: boolean
|
||||||
setDescription: boolean
|
setDescription: boolean
|
||||||
|
|||||||
@@ -552,6 +552,12 @@ function OverflowMenu({
|
|||||||
const {mutate: setReferenceListOptOut, isPending: isOptOutPending} =
|
const {mutate: setReferenceListOptOut, isPending: isOptOutPending} =
|
||||||
useReferenceListOptOutMutation({
|
useReferenceListOptOutMutation({
|
||||||
starterPack,
|
starterPack,
|
||||||
|
onSuccess: action => {
|
||||||
|
ax.metric('starterPack:optOut', {
|
||||||
|
starterPack: starterPack.uri,
|
||||||
|
action,
|
||||||
|
})
|
||||||
|
},
|
||||||
onError: error => {
|
onError: error => {
|
||||||
logger.error('Failed to update starter pack opt-out', {
|
logger.error('Failed to update starter pack opt-out', {
|
||||||
safeMessage: error,
|
safeMessage: error,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const createdOptOut =
|
|||||||
const indexedOptOut =
|
const indexedOptOut =
|
||||||
'at://did:plc:viewer/app.bsky.graph.referencelistoptout/indexed'
|
'at://did:plc:viewer/app.bsky.graph.referencelistoptout/indexed'
|
||||||
|
|
||||||
function setup() {
|
function setup({onSuccess = jest.fn()} = {}) {
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {gcTime: Infinity, retry: false},
|
queries: {gcTime: Infinity, retry: false},
|
||||||
@@ -57,11 +57,11 @@ function setup() {
|
|||||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||||
)
|
)
|
||||||
const hook = renderHook(
|
const hook = renderHook(
|
||||||
() => useReferenceListOptOutMutation({starterPack, onError}),
|
() => useReferenceListOptOutMutation({starterPack, onError, onSuccess}),
|
||||||
{wrapper},
|
{wrapper},
|
||||||
)
|
)
|
||||||
|
|
||||||
return {appviewClient, hook, onError, pdsClient, queryClient}
|
return {appviewClient, hook, onError, onSuccess, pdsClient, queryClient}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -76,7 +76,7 @@ beforeAll(() => {
|
|||||||
|
|
||||||
describe('useReferenceListOptOutMutation', () => {
|
describe('useReferenceListOptOutMutation', () => {
|
||||||
it('keeps the successful PDS write optimistic when AppView has not caught up', async () => {
|
it('keeps the successful PDS write optimistic when AppView has not caught up', async () => {
|
||||||
const {hook, pdsClient, queryClient} = setup()
|
const {hook, onSuccess, pdsClient, queryClient} = setup()
|
||||||
pdsClient.create.mockResolvedValue({uri: createdOptOut})
|
pdsClient.create.mockResolvedValue({uri: createdOptOut})
|
||||||
jest.mocked(until).mockResolvedValue(false)
|
jest.mocked(until).mockResolvedValue(false)
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@ describe('useReferenceListOptOutMutation', () => {
|
|||||||
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
||||||
?.list?.viewer?.referenceListOptOut,
|
?.list?.viewer?.referenceListOptOut,
|
||||||
).toBe(createdOptOut)
|
).toBe(createdOptOut)
|
||||||
|
expect(onSuccess).toHaveBeenCalledWith('optOut')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uses the indexed viewer-state URI when AppView reports a duplicate', async () => {
|
it('uses the indexed viewer-state URI when AppView reports a duplicate', async () => {
|
||||||
@@ -121,7 +122,7 @@ describe('useReferenceListOptOutMutation', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('deletes the viewer-state record URI when undoing', async () => {
|
it('deletes the viewer-state record URI when undoing', async () => {
|
||||||
const {hook, pdsClient, queryClient} = setup()
|
const {hook, onSuccess, pdsClient, queryClient} = setup()
|
||||||
queryClient.setQueryData(queryKey, {
|
queryClient.setQueryData(queryKey, {
|
||||||
...starterPack,
|
...starterPack,
|
||||||
list: {
|
list: {
|
||||||
@@ -148,10 +149,11 @@ describe('useReferenceListOptOutMutation', () => {
|
|||||||
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
||||||
?.list?.viewer?.referenceListOptOut,
|
?.list?.viewer?.referenceListOptOut,
|
||||||
).toBeUndefined()
|
).toBeUndefined()
|
||||||
|
expect(onSuccess).toHaveBeenCalledWith('undo')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('restores viewer state and surfaces PDS write failures', async () => {
|
it('restores viewer state and surfaces PDS write failures', async () => {
|
||||||
const {hook, onError, pdsClient, queryClient} = setup()
|
const {hook, onError, onSuccess, pdsClient, queryClient} = setup()
|
||||||
const error = new Error('write failed')
|
const error = new Error('write failed')
|
||||||
pdsClient.create.mockRejectedValue(error)
|
pdsClient.create.mockRejectedValue(error)
|
||||||
|
|
||||||
@@ -162,6 +164,7 @@ describe('useReferenceListOptOutMutation', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await waitFor(() => expect(onError).toHaveBeenCalledWith(error))
|
await waitFor(() => expect(onError).toHaveBeenCalledWith(error))
|
||||||
|
expect(onSuccess).not.toHaveBeenCalled()
|
||||||
expect(
|
expect(
|
||||||
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
queryClient.getQueryData<app.bsky.graph.defs.StarterPackView>(queryKey)
|
||||||
?.list?.viewer?.referenceListOptOut,
|
?.list?.viewer?.referenceListOptOut,
|
||||||
|
|||||||
@@ -74,9 +74,11 @@ export function useStarterPackQuery({
|
|||||||
export function useReferenceListOptOutMutation({
|
export function useReferenceListOptOutMutation({
|
||||||
starterPack,
|
starterPack,
|
||||||
onError,
|
onError,
|
||||||
|
onSuccess,
|
||||||
}: {
|
}: {
|
||||||
starterPack: app.bsky.graph.defs.StarterPackView
|
starterPack: app.bsky.graph.defs.StarterPackView
|
||||||
onError: (error: Error) => void
|
onError: (error: Error) => void
|
||||||
|
onSuccess?: (action: 'optOut' | 'undo') => void
|
||||||
}) {
|
}) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const appviewClient = useAppviewClient()
|
const appviewClient = useAppviewClient()
|
||||||
@@ -171,7 +173,7 @@ export function useReferenceListOptOutMutation({
|
|||||||
)
|
)
|
||||||
return {previous}
|
return {previous}
|
||||||
},
|
},
|
||||||
onSuccess: ({referenceListOptOut}) => {
|
onSuccess: ({referenceListOptOut}, variables) => {
|
||||||
queryClient.setQueryData<app.bsky.graph.defs.StarterPackView>(
|
queryClient.setQueryData<app.bsky.graph.defs.StarterPackView>(
|
||||||
queryKey,
|
queryKey,
|
||||||
current =>
|
current =>
|
||||||
@@ -192,6 +194,7 @@ export function useReferenceListOptOutMutation({
|
|||||||
queryClient,
|
queryClient,
|
||||||
uri: starterPack.list!.uri,
|
uri: starterPack.list!.uri,
|
||||||
})
|
})
|
||||||
|
onSuccess?.(variables.referenceListOptOut ? 'undo' : 'optOut')
|
||||||
},
|
},
|
||||||
onError: (error, _, context) => {
|
onError: (error, _, context) => {
|
||||||
if (context?.previous) {
|
if (context?.previous) {
|
||||||
|
|||||||
Reference in New Issue
Block a user