Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PBI Transaction History #77

Merged
merged 7 commits into from
May 17, 2024
Merged
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
26 changes: 17 additions & 9 deletions __tests__/payment/payment-details-with-url.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ jest.mock('next/navigation', () => ({
})),
}))

const mockTransaction = {
package: { name: 'Test Package' },
payment_type: 'Test Payment Type',
payment_merchant: 'Test Payment Merchant',
midtrans_url: 'https://example.com/midtrans',
}

jest.mock('@/redux/api/paymentApi', () => ({
useLazyGetTransactionQuery: jest.fn(() => [
jest.fn(),
{
data: {
transaction_detail: {
package: { name: 'Test Package' },
payment_type: 'Test Payment Type',
payment_merchant: 'Test Payment Merchant',
midtrans_url: 'https://example.com/midtrans',
},
transaction_detail: mockTransaction,
},
isLoading: false,
},
Expand All @@ -36,10 +38,16 @@ describe('Payment Detail Page With Midtrans Url', () => {
expect(queryByTestId('loader')).not.toBeInTheDocument()
})

expect(getByText('Transaction Detail')).toBeInTheDocument()
expect(getByText('Transaction detail')).toBeInTheDocument()
expect(getByText('Test Package')).toBeInTheDocument()
expect(getByText('Test Payment Type')).toBeInTheDocument()
expect(getByText('Test Payment Merchant')).toBeInTheDocument()
expect(getByText('Payment Type')).toBeInTheDocument()
expect(getByText('Merchant')).toBeInTheDocument()
expect(
getByText(mockTransaction.payment_type.toUpperCase())
).toBeInTheDocument()
expect(
getByText(mockTransaction.payment_merchant.toUpperCase())
).toBeInTheDocument()

fireEvent.click(getByText('Continue Transaction'))

Expand Down
70 changes: 70 additions & 0 deletions __tests__/payment/payment-fail.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { render, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import { useLazyGetTransactionQuery } from '@/redux/api/paymentApi'
import PaymentPage from '@/app/payment/page'

jest.mock('next/link', () => {
const MockedLink = ({ children, href }: any) => <a href={href}>{children}</a>

MockedLink.displayName = 'MockedNextLink'

return MockedLink
})

jest.mock('next/navigation', () => ({
useSearchParams: jest.fn(() => ({
get: jest.fn((param) => {
switch (param) {
case 'order_id':
return 'test_order_id'
case 'transaction_status':
return 'deny'
default:
return null
}
}),
})),
}))

jest.mock('@/redux/api/paymentApi', () => ({
useLazyGetTransactionQuery: jest.fn(),
}))
describe('PaymentSuccess Component', () => {
it('renders the success message when data is loaded', async () => {
;(useLazyGetTransactionQuery as jest.Mock).mockReturnValue([
jest.fn(),
{
data: {
transaction_detail: {
id: 'transaction_id',
package: {
id: 2,
name: 'Premium',
},
midtrans_url: 'http:example.com',
midtrans_transaction_id: 'midtrans_id',
order_id: 'order_id',
price: 10000,
checkout_time: '2024-05-06T14:49:19Z',
expiry_time: '2024-05-06T15:04:19Z',
payment_type: 'qris',
payment_merchant: 'gopay',
status: 'deny',
},
},
isLoading: false,
},
])

const { getByText, getByRole } = render(<PaymentPage />)

await waitFor(() => {
expect(getByText('Payment Failed')).toBeInTheDocument()
const button = getByRole('button', { name: 'See Transaction History' })
expect(button.closest('a')).toHaveAttribute(
'href',
'/profile?tab=history'
)
})
})
})
33 changes: 14 additions & 19 deletions __tests__/payment/payment-success.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { render, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import PaymentSuccessPage from '@/app/payment/success/page'
import { useLazyGetTransactionQuery } from '@/redux/api/paymentApi'
import PaymentPage from '@/app/payment/page'

jest.mock('next/link', () => {
const MockedLink = ({ children, href }: any) => <a href={href}>{children}</a>
Expand All @@ -13,7 +13,16 @@ jest.mock('next/link', () => {

jest.mock('next/navigation', () => ({
useSearchParams: jest.fn(() => ({
get: jest.fn(() => 'test_order_id'),
get: jest.fn((param) => {
switch (param) {
case 'order_id':
return 'test_order_id'
case 'transaction_status':
return 'settlement'
default:
return null
}
}),
})),
}))

Expand Down Expand Up @@ -47,30 +56,16 @@ describe('PaymentSuccess Component', () => {
},
])

const { getByText, getByRole } = render(<PaymentSuccessPage />)
const { getByText, getByRole } = render(<PaymentPage />)

await waitFor(() => {
expect(getByText('Payment Success')).toBeInTheDocument()
expect(getByText('Premium')).toBeInTheDocument()
const button = getByRole('button', { name: 'Go to transactions' })
const button = getByRole('button', { name: 'See Transaction History' })
expect(button.closest('a')).toHaveAttribute(
'href',
'/payment/transactions/'
'/profile?tab=history'
)
})
})

it('shows loader when data is still loading', () => {
;(useLazyGetTransactionQuery as jest.Mock).mockReturnValue([
jest.fn(),
{
data: null,
isLoading: true,
},
])

const { getByTestId } = render(<PaymentSuccessPage />)

expect(getByTestId('loader')).toBeInTheDocument()
})
})
121 changes: 120 additions & 1 deletion __tests__/profile/profile.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import '@testing-library/jest-dom'
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import {
render,
screen,
fireEvent,
getAllByAltText,
} from '@testing-library/react'
import { Provider } from 'react-redux'
import { store } from '@/redux/store'
import { useGetProfileQuery, useGetEventsQuery } from '@/redux/api/profileApi'
import Profile from '@/app/profile/page'
import { useGetSubscriptionsQuery } from '@/redux/api/subscriptionApi'
import { useGetTransactionListQuery } from '@/redux/api/paymentApi'
import { formatRupiah } from '@/utils/formatRupiah'
import { formatDateTime } from '@/utils/formatDateTime'

jest.mock('next/navigation', () => ({
useSearchParams: jest.fn(() => ({
get: jest.fn(() => undefined),
})),
}))

const mockEventsData = [
{
Expand All @@ -19,6 +33,53 @@ const mockEventsData = [
services: 'Live Music, Food Stalls, Security',
},
]
const mockTransactionData = [
{
id: 'mock-id-1',
package: {
name: 'Premium',
},
midtrans_url: null,
midtrans_transaction_id: 'mid-1',
order_id: 'ord-1',
price: 10000,
checkout_time: '2024-05-06T14:49:19Z',
expiry_time: '2024-05-06T15:04:19Z',
payment_type: 'qris',
payment_merchant: 'gopay',
status: 'settlement',
},
{
id: 'mock-id-2',
package: {
name: 'Premium',
},
midtrans_url: null,
midtrans_transaction_id: 'mid-2',
order_id: 'ord-2',
price: 10000,
checkout_time: '2024-05-04T14:49:19Z',
expiry_time: '2024-05-04T15:04:19Z',
payment_type: 'qris',
payment_merchant: 'gopay',
status: 'failed',
},
{
id: 'mock-id-3',
package: {
name: 'Premium',
},
midtrans_url: null,
midtrans_transaction_id: 'mid-3',
order_id: 'ord-3',
price: 10000,
checkout_time: '2024-05-03T14:49:19Z',
expiry_time: '2024-05-03T15:04:19Z',
payment_type: 'qris',
payment_merchant: 'gopay',
status: 'pending',
},
]

jest.mock('@/redux/api/subscriptionApi', () => ({
useGetSubscriptionsQuery: jest.fn().mockReturnValue({
Expand Down Expand Up @@ -53,6 +114,10 @@ jest.mock('@/redux/api/profileApi', () => ({
useGetEventsQuery: jest.fn(),
}))

jest.mock('@/redux/api/paymentApi', () => ({
useGetTransactionListQuery: jest.fn(),
}))

Object.defineProperty(window, 'location', {
value: { pathname: '/mock-path' },
})
Expand All @@ -75,6 +140,10 @@ describe('Profile Component', () => {
isLoading: false,
isError: false,
})
;(useGetTransactionListQuery as jest.Mock).mockReturnValue({
data: mockTransactionData,
isLoading: false,
})
})

it('displays error state correctly', () => {
Expand Down Expand Up @@ -190,4 +259,54 @@ describe('Profile Component', () => {
</Provider>
)
})

it('displays transaction information when there is at least one transaction', () => {
const myInitialState = 'history'
React.useState = jest.fn().mockReturnValue([myInitialState, {}])

const { getByText, getAllByText } = render(
<Provider store={store}>
<Profile />
</Provider>
)

expect(getByText('Checkout Time')).toBeInTheDocument()
expect(getByText('Package Plan')).toBeInTheDocument()
expect(getByText('Price')).toBeInTheDocument()
expect(getByText('Expiry Time')).toBeInTheDocument()
expect(getByText('Status')).toBeInTheDocument()
expect(
getByText(mockTransactionData[0].status.toUpperCase())
).toBeInTheDocument()
expect(
getAllByText(formatRupiah(mockTransactionData[0].price))[0]
).toBeInTheDocument()
expect(
getByText(formatDateTime(mockTransactionData[0].checkout_time))
).toBeInTheDocument()
expect(
getByText(formatDateTime(mockTransactionData[0].expiry_time))
).toBeInTheDocument()
})

it('displays no transaction information', () => {
const myInitialState = 'history'
React.useState = jest.fn().mockReturnValue([myInitialState, {}])
;(useGetTransactionListQuery as jest.Mock).mockReturnValue({
data: [],
isLoading: false,
})
const { getByText } = render(
<Provider store={store}>
<Profile />
</Provider>
)

expect(getByText('Checkout Time')).toBeInTheDocument()
expect(getByText('Package Plan')).toBeInTheDocument()
expect(getByText('Price')).toBeInTheDocument()
expect(getByText('Expiry Time')).toBeInTheDocument()
expect(getByText('Status')).toBeInTheDocument()
expect(getByText('No transactions recorded')).toBeInTheDocument()
})
})
8 changes: 3 additions & 5 deletions __tests__/task-detail/task-detail-with-step.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
useUpdateTaskStepMutation,
} from '@/redux/api/taskStepApi'
import '@testing-library/jest-dom'
import dayjs from '@/configs/dayjs.config'
import { Step } from '@/types/taskDetails'
import { store } from '@/redux/store'
import { Provider } from 'react-redux'
import { formatDateTime } from '@/utils/formatDateTime'

jest.mock('@/redux/api/eventApi', () => ({
useGetEventQuery: jest.fn(),
Expand Down Expand Up @@ -312,12 +312,10 @@ describe('TaskDetailPage with step', () => {
)

expect(
screen.getByText(
dayjs(mockStepData.start_datetime).format('ddd, D MMM YY HH:mm')
)
screen.getByText(formatDateTime(mockStepData.start_datetime))
).toBeInTheDocument()
expect(
screen.getByText(dayjs(mockStepData.end_datetime).format('HH:mm'))
screen.getByText(formatDateTime(mockStepData.end_datetime, 'HH:mm'))
).toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ConfirmDeleteDialog from './ConfirmDeleteDialog'
import { CreateTimelineDialog } from './CreateTimelineDialog'
import dayjs from '@/configs/dayjs.config'
import { twMerge } from 'tailwind-merge'
import { formatDateTime } from '@/utils/formatDateTime'

export type StepUpdateRequest = {
name: string
Expand Down Expand Up @@ -191,14 +192,12 @@ export default function StepStepper({ taskId, task }: Props) {
<StepContent>
<div className="text-sm font-bold flex flex-row items-center gap-2 text-gray-700">
<i className="i-ph-calendar-blank size-4 text-gray-700" />
<p>
{dayjs(step.start_datetime).format('ddd, D MMM YY HH:mm')}
</p>
<p>{formatDateTime(step.start_datetime)}</p>
<p>-</p>
<p>
{dayjs(step.start_datetime).isSame(step.end_datetime, 'day')
? dayjs(step.end_datetime).format('HH:mm')
: dayjs(step.end_datetime).format('ddd, D MMM YY HH:mm')}
? formatDateTime(step.end_datetime, 'HH:mm')
: formatDateTime(step.end_datetime)}
</p>
</div>
<Typography>{step.description}</Typography>
Expand Down
Loading
Loading