Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ bv-pages/

# Local backup files
prisma/backups/
.zed/
69 changes: 69 additions & 0 deletions app/routes/__tests__/dashboard.purchase.verify.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { redirect } from '@remix-run/node'
import { loader } from '../dashboard.purchase.verify'
import { TRANSACTION_STATUS } from '~/models/enum'
import { requireUser } from '~/services/auth.server'
import { getFirstTransaction } from '~/models/transaction'

vi.mock('~/services/auth.server', () => ({
requireUser: vi.fn(),
}))

vi.mock('~/models/transaction', () => ({
getFirstTransaction: vi.fn(),
}))

function buildRequest(url = 'http://example.com/dashboard/purchase/verify') {
return new Request(url, { method: 'GET' })
}

const fakeUser = { id: 'user-1', email: 'test@example.com' }

describe('dashboard.purchase.verify loader', () => {
beforeEach(() => {
vi.mocked(requireUser).mockResolvedValue(fakeUser as never)
})

it('redirects to /dashboard/purchase when no transaction exists', async () => {
vi.mocked(getFirstTransaction).mockResolvedValue(null)

const response = await loader({
request: buildRequest(),
params: {},
context: {},
})

expect(response).toEqual(redirect('/dashboard/purchase'))
})

it('redirects to /dashboard/purchase/completed when transaction is VERIFIED', async () => {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice regression case. Covering the VERIFIED redirect in the loader makes the dead-code removal in dashboard.purchase.verify much safer against future regressions.

vi.mocked(getFirstTransaction).mockResolvedValue({
id: 'tx-1',
status: TRANSACTION_STATUS.VERIFIED,
} as never)

const response = await loader({
request: buildRequest(),
params: {},
context: {},
})

expect(response).toEqual(redirect('/dashboard/purchase/completed'))
})

it('returns transaction and user when transaction is not verified', async () => {
const fakeTransaction = {
id: 'tx-1',
status: TRANSACTION_STATUS.SUBMITTED,
}
vi.mocked(getFirstTransaction).mockResolvedValue(fakeTransaction as never)

const response = await loader({
request: buildRequest(),
params: {},
context: {},
})

expect(response).toEqual({ transaction: fakeTransaction, user: fakeUser })
})
})
1 change: 0 additions & 1 deletion app/routes/dashboard.purchase.completed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export default function Completed() {
}>()
return (
<>
{/* TODO: Render action buttons conditionally */}
<TransactionDetails transaction={transaction} user={user}>
<SecondaryButtonLink to={getWhatsAppLink(authorPhoneNumber)} external>
Kontak Admin
Expand Down
12 changes: 2 additions & 10 deletions app/routes/dashboard.purchase.verify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,11 @@ export default function Verify() {
useLoaderData<{ transaction: Transaction; user: User }>()
return (
<>
{/* TODO: Render action buttons conditionally */}
<TransactionDetails transaction={transaction} user={user}>
<SecondaryButtonLink
to="/dashboard/purchase/confirm"
disabled={transaction.status === TRANSACTION_STATUS.VERIFIED}
>
<SecondaryButtonLink to="/dashboard/purchase/confirm">
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dead-code reasoning checks out here, but after removing the UI-level guard this route now depends entirely on the loader redirect above to keep VERIFIED transactions from ever rendering these links. I couldn't find a purchase-route test covering that invariant. Could we add a small regression test that a verified transaction is redirected to /dashboard/purchase/completed? That would make this cleanup much safer against future refactors.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated the invariant here: loader() redirects any VERIFIED transaction to /dashboard/purchase/completed before this component can render, so removing the disabled={transaction.status === TRANSACTION_STATUS.VERIFIED} prop does not appear to change any reachable UI state.

Ubah Detail Transaksi
</SecondaryButtonLink>
<PrimaryButtonLink
to={transaction.id}
replace
disabled={transaction.status === TRANSACTION_STATUS.VERIFIED}
>
<PrimaryButtonLink to={transaction.id} replace>
Verifikasi Pembelian
</PrimaryButtonLink>
</TransactionDetails>
Expand Down
Loading