🐛 (import) fix YNAB (and other) importers (#1462)

This commit is contained in:
Matiss Janis Aboltins
2023-08-05 13:42:43 +01:00
committed by GitHub
parent cd54a2093e
commit 7b7e6e4db0
10 changed files with 1737 additions and 23 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -41,8 +41,21 @@ test.describe('Onboarding', () => {
await expect(accountPage.accountBalance).toHaveText('2,607.00');
});
// TODO: implement this test once we have an example nYNAB file
// test('creates a new budget file by importing nYNAB budget');
test('creates a new budget file by importing nYNAB budget', async () => {
await configurationPage.clickOnNoServer();
const budgetPage = await configurationPage.importBudget(
'nYNAB',
path.resolve(__dirname, 'data/ynab5-demo-budget.json'),
);
await expect(budgetPage.budgetTable).toBeVisible({ timeout: 30000 });
const accountPage = await navigation.goToAccountPage('Checking');
await expect(accountPage.accountBalance).toHaveText('700.00');
await navigation.goToAccountPage('Saving');
await expect(accountPage.accountBalance).toHaveText('200.00');
});
test('creates a new budget file by importing Actual budget', async () => {
await configurationPage.clickOnNoServer();

View File

@@ -6,11 +6,11 @@ import { importBudget } from 'loot-core/src/client/actions/budgets';
import { styles, colors } from '../../style';
import Block from '../common/Block';
import { ButtonWithLoading } from '../common/Button';
import Modal from '../common/Modal';
import Modal, { type ModalProps } from '../common/Modal';
import Paragraph from '../common/Paragraph';
import View from '../common/View';
function getErrorMessage(error) {
function getErrorMessage(error: string): string {
switch (error) {
case 'parse-error':
return 'Unable to parse file. Please select a JSON file exported from nYNAB.';
@@ -27,9 +27,13 @@ function getErrorMessage(error) {
}
}
function Import({ modalProps }) {
type ImportProps = {
modalProps?: ModalProps;
};
function Import({ modalProps }: ImportProps) {
const dispatch = useDispatch();
const [error, setError] = useState(false);
const [error, setError] = useState<string | null>(null);
const [importing, setImporting] = useState(false);
async function onImport() {
@@ -39,7 +43,7 @@ function Import({ modalProps }) {
});
if (res) {
setImporting(true);
setError(false);
setError(null);
try {
await dispatch(importBudget(res[0], 'actual'));
} catch (err) {

View File

@@ -6,11 +6,11 @@ import { importBudget } from 'loot-core/src/client/actions/budgets';
import { styles, colors } from '../../style';
import Block from '../common/Block';
import { ButtonWithLoading } from '../common/Button';
import Modal from '../common/Modal';
import Modal, { type ModalProps } from '../common/Modal';
import Paragraph from '../common/Paragraph';
import View from '../common/View';
function getErrorMessage(error) {
function getErrorMessage(error: string): string {
switch (error) {
case 'not-ynab4':
return 'This file is not valid. Please select a compressed ynab4 zip file.';
@@ -19,9 +19,13 @@ function getErrorMessage(error) {
}
}
function Import({ modalProps }) {
type ImportProps = {
modalProps?: ModalProps;
};
function Import({ modalProps }: ImportProps) {
const dispatch = useDispatch();
const [error, setError] = useState(false);
const [error, setError] = useState<string | null>(null);
const [importing, setImporting] = useState(false);
async function onImport() {
@@ -31,7 +35,7 @@ function Import({ modalProps }) {
});
if (res) {
setImporting(true);
setError(false);
setError(null);
try {
await dispatch(importBudget(res[0], 'ynab4'));
} catch (err) {

View File

@@ -7,11 +7,11 @@ import { styles, colors } from '../../style';
import Block from '../common/Block';
import { ButtonWithLoading } from '../common/Button';
import ExternalLink from '../common/ExternalLink';
import Modal from '../common/Modal';
import Modal, { type ModalProps } from '../common/Modal';
import Paragraph from '../common/Paragraph';
import View from '../common/View';
function getErrorMessage(error) {
function getErrorMessage(error: string): string {
switch (error) {
case 'parse-error':
return 'Unable to parse file. Please select a JSON file exported from nYNAB.';
@@ -22,9 +22,13 @@ function getErrorMessage(error) {
}
}
function Import({ modalProps }) {
type ImportProps = {
modalProps?: ModalProps;
};
function Import({ modalProps }: ImportProps) {
const dispatch = useDispatch();
const [error, setError] = useState(false);
const [error, setError] = useState<string | null>(null);
const [importing, setImporting] = useState(false);
async function onImport() {
@@ -34,7 +38,7 @@ function Import({ modalProps }) {
});
if (res) {
setImporting(true);
setError(false);
setError(null);
try {
await dispatch(importBudget(res[0], 'ynab5'));
} catch (err) {

View File

@@ -147,7 +147,6 @@ export function handleGlobalEvents(actions, store) {
listen('start-import', () => {
actions.closeBudgetUI();
actions.setAppState({ loadingText: 'Importing...' });
});
listen('finish-import', () => {

View File

@@ -2,7 +2,8 @@
export namespace YNAB5 {
export interface Budget {
budget_name: string;
name?: string;
budget_name?: string;
accounts: Account[];
payees: Payee[];
category_groups: CategoryGroup[];

View File

@@ -294,10 +294,13 @@ export function parseFile(buffer: Buffer): YNAB5.Budget {
if (data.data) {
data = data.data;
}
if (data.budget) {
data = data.budget;
}
return data;
}
export function getBudgetName(_filepath: string, data: YNAB5.Budget) {
return data.budget_name;
return data.budget_name || data.name;
}

View File

@@ -2053,14 +2053,13 @@ handlers['import-budget'] = async function ({ filepath, type }) {
}
let buffer = Buffer.from(await fs.readFile(filepath, 'binary'));
await handleBudgetImport(type, filepath, buffer);
let results = await handleBudgetImport(type, filepath, buffer);
return results || {};
} catch (err) {
err.message = 'Error importing budget: ' + err.message;
captureException(err);
return { error: 'internal-error' };
}
return {};
};
handlers['export-budget'] = async function () {

View File

@@ -0,0 +1,6 @@
---
category: Bugfix
authors: [MatissJanis]
---
Fix import from nYNAB and error-handling of other importers