Skip to content

Commit

Permalink
test: add missing tests for report reducers and effects
Browse files Browse the repository at this point in the history
  • Loading branch information
grantwforsythe committed Apr 12, 2024
1 parent 574f3ff commit f0f92cb
Show file tree
Hide file tree
Showing 4 changed files with 349 additions and 3 deletions.
144 changes: 144 additions & 0 deletions src/app/reports/data-access/report.effects.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { TestBed } from '@angular/core/testing';

import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { provideMockStore } from '@ngrx/store/testing';

import { Observable, of } from 'rxjs';

import { YnabService } from '../../shared/services/ynab/ynab.service';
import {
mockAccounts,
mockCategoryGroups,
mockId,
mockTransactions,
} from '../../shared/utils/mocks';
import { reportActions } from './report.actions';
import { ReportEffects } from './report.effects';

describe('ReportEffects', () => {
let actions$: Observable<Action>;
let effects: ReportEffects;
let ynabSpy: jasmine.SpyObj<YnabService>;

const initialState = {
router: {
state: {
root: {
params: {},
data: {},
url: [],
outlet: 'primary',
routeConfig: null,
queryParams: {},
fragment: null,
firstChild: {
params: {
id: mockId,
},
data: {},
url: [
{
path: 'budgets',
parameters: {},
},
{
path: mockId,
parameters: {},
},
{
path: 'dashboard',
parameters: {},
},
],
outlet: 'primary',
routeConfig: {
path: 'budgets/:id/dashboard',
},
queryParams: {},
fragment: null,
children: [],
},
children: [
{
params: {
mockId: mockId,
},
data: {},
url: [
{
path: 'budgets',
parameters: {},
},
{
path: mockId,
parameters: {},
},
{
path: 'dashboard',
parameters: {},
},
],
outlet: 'primary',
routeConfig: {
path: 'budgets/:id/dashboard',
},
queryParams: {},
fragment: null,
children: [],
},
],
},
url: `/budgets/${mockId}/dashboard`,
},
navigationId: 3,
},
};

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
ReportEffects,
provideMockActions(() => actions$),
provideMockStore({ initialState }),
{
provide: YnabService,
useValue: jasmine.createSpyObj('YnabService', [
'getCategoryGroups',
'getAccounts',
'getTransactions',
]),
},
],
});

actions$ = TestBed.inject(Actions);
effects = TestBed.inject(ReportEffects);
ynabSpy = TestBed.inject(YnabService) as jasmine.SpyObj<YnabService>;
});

describe('loadBudgetResources$', () => {
// TODO: Test for invalid ID
it('should dispatch setReportData when initReportData is dispatched', () => {
actions$ = of({ type: '[Dashboard Page] Init Report Data' });
ynabSpy.getCategoryGroups.and.returnValue(of(mockCategoryGroups));
ynabSpy.getAccounts.and.returnValue(of(mockAccounts));
ynabSpy.getTransactions.and.returnValue(of(mockTransactions));

effects.loadBudgetResources$.subscribe((action) => {
expect(action).toEqual(
reportActions.setReportData({
accounts: mockAccounts,
categoryGroups: mockCategoryGroups,
transactions: mockTransactions,
}),
);
});

expect(ynabSpy.getCategoryGroups).toHaveBeenCalledWith(mockId);
expect(ynabSpy.getAccounts).toHaveBeenCalledWith(mockId);
expect(ynabSpy.getTransactions).toHaveBeenCalledWith(mockId);
});
});
});
40 changes: 40 additions & 0 deletions src/app/reports/data-access/report.reducers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { mockAccounts, mockCategoryGroups, mockTransactions } from '../../shared/utils/mocks';
import { reportActions } from './report.actions';
import * as fromReducer from './report.reducers';

describe('Report Reducer', () => {
describe('an unknown action', () => {
it('should return the initial state', () => {
const action = { type: 'Unknown' };
const result = fromReducer.reportReducer(fromReducer.initialState, action);

expect(result).toBe(fromReducer.initialState);
});
});

describe('#setReportData()', () => {
it('should set the state with the provided categories, accounts, and transactions', () => {
const action = reportActions.setReportData({
categoryGroups: mockCategoryGroups,
accounts: mockAccounts,
transactions: mockTransactions,
});

const result = fromReducer.reportReducer(fromReducer.initialState, action);

expect(result.categoryGroups).toEqual(mockCategoryGroups);
expect(result.accounts).toEqual(mockAccounts);
expect(result.transactions).toEqual(mockTransactions);
});
});

describe('#resetReportData()', () => {
it('should return the initial state', () => {
const action = reportActions.resetReportData();

const result = fromReducer.reportReducer(fromReducer.initialState, action);

expect(result).toEqual(fromReducer.initialState);
});
});
});
5 changes: 2 additions & 3 deletions src/app/reports/data-access/report.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ interface ReportState {
transactions: Transaction[];
}

const initialState: ReportState = {
export const initialState: ReportState = {
categoryGroups: [],
accounts: [],
transactions: [],
};

export const reportReducer = createReducer(
initialState,
on(reportActions.setReportData, (state, action): ReportState => {
on(reportActions.setReportData, (_state, action): ReportState => {
return {
...state,
categoryGroups: action.categoryGroups,
accounts: action.accounts,
transactions: action.transactions,
Expand Down
163 changes: 163 additions & 0 deletions src/app/shared/utils/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { Account } from '../services/ynab/interfaces/accounts/account';
import { BudgetSummary } from '../services/ynab/interfaces/budgets/summary/budgetSummary';
import { CategoryGroup } from '../services/ynab/interfaces/categories/categoryGroup';
import { Payee } from '../services/ynab/interfaces/payees/payee';
import { Transaction } from '../services/ynab/interfaces/transactions/transaction';

// TODO: Change the id for each mock

// TODO: Rename to mockBudgetId
export const mockId = '3fa85f64-5717-4562-b3fc-2c963f66afa6';

export const mockBudgets: BudgetSummary[] = [
{
id: mockId,
name: 'string',
last_modified_on: '2024-04-11T20:44:53.501Z',
first_month: '2024-04-11',
last_month: '2024-04-11',
date_format: {
format: 'MM/DD/YYYY',
},
currency_format: {
iso_code: 'string',
example_format: 'string',
decimal_digits: 0,
decimal_separator: 'string',
symbol_first: true,
group_separator: 'string',
currency_symbol: 'string',
display_symbol: true,
},
},
{
id: '2fa85f64-5717-4562-b3fc-2c963f66afa6',
name: 'string',
last_modified_on: '2024-04-11T20:44:53.501Z',
first_month: '2024-04-11',
last_month: '2024-04-11',
date_format: {
format: 'MM/DD/YYYY',
},
currency_format: {
iso_code: 'string',
example_format: 'string',
decimal_digits: 0,
decimal_separator: 'string',
symbol_first: true,
group_separator: 'string',
currency_symbol: 'string',
display_symbol: true,
},
},
];

export const mockCategoryGroups: CategoryGroup[] = [
{
id: mockId,
name: 'string',
hidden: true,
deleted: true,
categories: [
{
id: mockId,
category_group_id: mockId,
category_group_name: 'string',
name: 'string',
hidden: true,
original_category_group_id: mockId,
note: 'string',
budgeted: 0,
activity: 0,
balance: 0,
goal_type: 'TB',
goal_day: 0,
goal_cadence: 0,
goal_cadence_frequency: 0,
goal_creation_month: '2024-03-09',
goal_target: 0,
goal_target_month: '2024-03-09',
goal_percentage_complete: 0,
goal_months_to_budget: 0,
goal_under_funded: 0,
goal_overall_funded: 0,
goal_overall_left: 0,
deleted: true,
},
],
},
];

export const mockPayees: Payee[] = [
{
id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
name: 'string',
transfer_account_id: 'string',
deleted: true,
},
];

export const mockAccounts: Account[] = [
{
id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
name: 'string',
type: 'checking',
on_budget: true,
closed: true,
note: 'string',
balance: 0,
cleared_balance: 0,
uncleared_balance: 0,
transfer_payee_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
direct_import_linked: true,
direct_import_in_error: true,
last_reconciled_at: '2024-03-14T02:39:28.300Z',
debt_original_balance: 0,
debt_interest_rates: {},
debt_minimum_payments: {},
debt_escrow_amounts: {},
deleted: true,
},
];

export const mockTransactions: Transaction[] = [
{
id: mockId,
date: '2024-03-09',
amount: 0,
memo: 'string',
cleared: 'cleared',
approved: true,
flag_color: 'red',
flag_name: 'string',
account_id: mockId,
payee_id: mockId,
category_id: mockId,
transfer_account_id: mockId,
transfer_transaction_id: mockId,
matched_transaction_id: mockId,
import_id: mockId,
import_payee_name: 'string',
import_payee_name_original: 'string',
debt_transaction_type: 'payment',
deleted: true,
account_name: 'string',
payee_name: 'string',
category_name: 'string',
subtransactions: [
{
id: mockId,
transaction_id: mockId,
amount: 0,
memo: 'string',
payee_id: mockId,
payee_name: 'string',
category_id: mockId,
category_name: 'string',
transfer_account_id: mockId,
transfer_transaction_id: mockId,
deleted: true,
},
],
},
];

0 comments on commit f0f92cb

Please sign in to comment.