Skip to content

Commit

Permalink
fix: do not require MoneyMoney accounts and categories to have an icon
Browse files Browse the repository at this point in the history
prior to this change the app would not work when no valid icon was received from MM
no idea in which cases this happnens but anyhow...

fix #61
  • Loading branch information
Xiphe committed Sep 15, 2020
1 parent 4c1f21f commit 05a362c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 38 deletions.
1 change: 1 addition & 0 deletions cypress/integration/budgetView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('Budget View', () => {
it('displays correct overview values', () => {
const incomeCategory = category({ name: 'Income this month' });
const spendingCategory = category();
delete spendingCategory.icon;
const myBudget = budget({
settings: settings({
startBalance: 100,
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/createNewBudget.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('Create New Budget', () => {
});

it('creates a new budget files with options', () => {
const accounts = [account(), account()];
const accounts = [account({ icon: undefined }), account()];
const categories = [category(), category(), category()];

cy.open({
Expand Down
19 changes: 17 additions & 2 deletions main/moneymoney/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,35 @@ function delay(t: number) {
return new Promise((r) => setTimeout(r, t));
}

function identify(thing: any) {
switch (true) {
case thing.budget !== undefined:
return `Category "${thing.name}"`;
case thing.accountNumber !== undefined:
return `Account "${thing.name}"`;
default:
return thing.name || thing;
}
}

function base64Icons(data: unknown) {
if (!Array.isArray(data)) {
throw new Error('Unexpectedly got non-array as data');
}

return data.map((entry: unknown) => {
if (entry === null || typeof entry !== 'object') {
if (typeof entry !== 'object' || entry === null) {
throw new Error('Unexpectedly got non-object in data array');
}

const icon: unknown = (entry as any).icon;

if (!(icon instanceof Buffer)) {
throw new Error(`Unexpectedly got ${typeof icon} as icon`);
console.warn(
`Unexpectedly got ${typeof icon} as icon in `,
identify(entry),
);
return entry;
}

return {
Expand Down
76 changes: 44 additions & 32 deletions src/moneymoney/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,42 +66,54 @@ const transactionsByAccountShape = t.array(
),
'transactions',
);
const interopAccountShape = t.type(
{
accountNumber: t.string,
const interopAccountShape = t.intersection([
t.type(
{
accountNumber: t.string,
name: t.string,
balance: t.array(t.tuple([t.number, t.string])),
currency: t.string,
group: t.boolean,
indentation: t.number,
portfolio: t.boolean,
uuid: t.string,
},
'account',
),
t.partial(
{
icon: t.string,
},
'accountOptional',
),
]);
const categoryShape = t.intersection([
t.type({
budget: t.union([
t.type({}),
t.type({
amount: t.number,
available: t.number,
period: t.union([
t.literal('monthly'),
t.literal('quarterly'),
t.literal('yearly'),
t.literal('total'),
]),
}),
]),
name: t.string,
balance: t.array(t.tuple([t.number, t.string])),
currency: t.string,
default: t.boolean,
group: t.boolean,

indentation: t.number,
icon: t.string,
portfolio: t.boolean,
uuid: t.string,
},
'account',
);
const categoryShape = t.type({
budget: t.union([
t.type({}),
t.type({
amount: t.number,
available: t.number,
period: t.union([
t.literal('monthly'),
t.literal('quarterly'),
t.literal('yearly'),
t.literal('total'),
]),
}),
]),
name: t.string,
currency: t.string,
default: t.boolean,
group: t.boolean,
icon: t.string,
indentation: t.number,
uuid: t.string,
});
}),
t.partial({
icon: t.string,
}),
]);

export type Category = t.TypeOf<typeof categoryShape>;
export type Transaction = t.TypeOf<typeof transactionShape>;
Expand All @@ -113,7 +125,7 @@ export type Account = {
group: boolean;
indentation: number;
portfolio: boolean;
icon: string;
icon?: string;
uuid: string;
number: string;
};
Expand Down
4 changes: 2 additions & 2 deletions src/moneymoney/getAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import memoizeOne from 'memoize-one';
const filterAccounts = memoizeOne(
(currency: string, interopAccounts: InteropAccount[]): Account[] => {
return interopAccounts
.map(
.map<Account | false>(
({
accountNumber,
balance,
Expand Down Expand Up @@ -35,7 +35,7 @@ const filterAccounts = memoizeOne(
};
},
)
.filter((data: Account | false): data is Account => Boolean(data));
.filter((data): data is Account => Boolean(data));
},
);

Expand Down
2 changes: 1 addition & 1 deletion src/views/CategorySidebar/CategorySidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default function CategorySidebar({
>
{!group && (
<span
style={{ backgroundImage: `url(${icon})` }}
style={icon ? { backgroundImage: `url(${icon})` } : {}}
className={styles.icon}
/>
)}
Expand Down

0 comments on commit 05a362c

Please sign in to comment.