Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into reportsUpdates
Browse files Browse the repository at this point in the history
  • Loading branch information
carkom committed Dec 6, 2023
2 parents 4ce468e + 2741422 commit 5bea94e
Show file tree
Hide file tree
Showing 240 changed files with 3,747 additions and 2,770 deletions.
23 changes: 21 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ module.exports = {

// TODO: re-enable these rules
'react-hooks/exhaustive-deps': 'off',
'react/no-children-prop': 'off',
'react/display-name': 'off',
'react/react-in-jsx-scope': 'off',
// 'react-hooks/exhaustive-deps': [
Expand Down Expand Up @@ -240,7 +239,27 @@ module.exports = {
'./packages/api/app/**/*',
'./packages/crdt/**/*',
'./packages/desktop-client/src/*',
// './packages/desktop-client/src/components/**/*',
'./packages/desktop-client/src/components/*',
'./packages/desktop-client/src/components/accounts/**/*',
'./packages/desktop-client/src/components/autocomplete/**/*',
'./packages/desktop-client/src/components/budget/**/*',
'./packages/desktop-client/src/components/common/**/*',
'./packages/desktop-client/src/components/filters/**/*',
'./packages/desktop-client/src/components/gocardless/**/*',
'./packages/desktop-client/src/components/manager/**/*',
'./packages/desktop-client/src/components/mobile/**/*',
'./packages/desktop-client/src/components/modals/**/*',
'./packages/desktop-client/src/components/payees/**/*',
'./packages/desktop-client/src/components/reports/**/*',
'./packages/desktop-client/src/components/responsive/**/*',
'./packages/desktop-client/src/components/rules/**/*',
'./packages/desktop-client/src/components/schedules/**/*',
'./packages/desktop-client/src/components/select/**/*',
'./packages/desktop-client/src/components/settings/**/*',
'./packages/desktop-client/src/components/sidebar/**/*',
'./packages/desktop-client/src/components/spreadsheet/**/*',
'./packages/desktop-client/src/components/transactions/**/*',
'./packages/desktop-client/src/components/util/**/*',
'./packages/desktop-client/src/hooks/**/*',
'./packages/desktop-client/src/icons/**/*',
'./packages/desktop-client/src/style/**/*',
Expand Down
250 changes: 250 additions & 0 deletions packages/api/methods.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import * as fs from 'fs/promises';
import * as path from 'path';

import * as api from './index';

const budgetName = 'test-budget';

beforeEach(async () => {
// we need real datetime if we are going to mix new timestamps with our mock data
global.restoreDateNow();

const budgetPath = path.join(__dirname, '/mocks/budgets/', budgetName);
await fs.rm(budgetPath, { force: true, recursive: true });

await createTestBudget('default-budget-template', budgetName);
await api.init({
dataDir: path.join(__dirname, '/mocks/budgets/'),
});
});

afterEach(async () => {
global.currentMonth = null;
await api.shutdown();
});

async function createTestBudget(templateName: string, name: string) {
const templatePath = path.join(
__dirname,
'/../loot-core/src/mocks/files',
templateName,
);
const budgetPath = path.join(__dirname, '/mocks/budgets/', name);

await fs.mkdir(budgetPath);
await fs.copyFile(
path.join(templatePath, 'metadata.json'),
path.join(budgetPath, 'metadata.json'),
);
await fs.copyFile(
path.join(templatePath, 'db.sqlite'),
path.join(budgetPath, 'db.sqlite'),
);
}

describe('API setup and teardown', () => {
// apis: loadBudget, getBudgetMonths
test('successfully loads budget', async () => {
await expect(api.loadBudget(budgetName)).resolves.toBeUndefined();

await expect(api.getBudgetMonths()).resolves.toMatchSnapshot();
});
});

describe('API CRUD operations', () => {
beforeEach(async () => {
// load test budget
await api.loadBudget(budgetName);
});

// apis: createCategoryGroup, updateCategoryGroup, deleteCategoryGroup
test('CategoryGroups: successfully update category groups', async () => {
const month = '2023-10';
global.currentMonth = month;

// create our test category group
const mainGroupId = await api.createCategoryGroup({
name: 'test-group',
});

let budgetMonth = await api.getBudgetMonth(month);
expect(budgetMonth.categoryGroups).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: mainGroupId,
}),
]),
);

// update group
await api.updateCategoryGroup(mainGroupId, {
name: 'update-tests',
});

budgetMonth = await api.getBudgetMonth(month);
expect(budgetMonth.categoryGroups).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: mainGroupId,
}),
]),
);

// delete group
await api.deleteCategoryGroup(mainGroupId);

budgetMonth = await api.getBudgetMonth(month);
expect(budgetMonth.categoryGroups).toEqual(
expect.arrayContaining([
expect.not.objectContaining({
id: mainGroupId,
}),
]),
);
});

// apis: createCategory, getCategories, updateCategory, deleteCategory
test('Categories: successfully update categories', async () => {
const month = '2023-10';
global.currentMonth = month;

// create our test category group
const mainGroupId = await api.createCategoryGroup({
name: 'test-group',
});
const secondaryGroupId = await api.createCategoryGroup({
name: 'test-secondary-group',
});
const categoryId = await api.createCategory({
name: 'test-budget',
group_id: mainGroupId,
});

let categories = await api.getCategories();
expect(categories).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: categoryId,
name: 'test-budget',
group_id: mainGroupId,
}),
]),
);

// update/move category
await api.updateCategory(categoryId, {
name: 'updated-budget',
group_id: secondaryGroupId,
});

categories = await api.getCategories();
expect(categories).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: categoryId,
name: 'updated-budget',
group_id: secondaryGroupId,
}),
]),
);

// delete categories
await api.deleteCategory(categoryId);

expect(categories).toEqual(
expect.arrayContaining([
expect.not.objectContaining({
id: categoryId,
}),
]),
);
});

// apis: setBudgetAmount, setBudgetCarryover, getBudgetMonth
test('Budgets: successfully update budgets', async () => {
const month = '2023-10';
global.currentMonth = month;

// create some new categories to test with
const groupId = await api.createCategoryGroup({
name: 'tests',
});
const categoryId = await api.createCategory({
name: 'test-budget',
group_id: groupId,
});

await api.setBudgetAmount(month, categoryId, 100);
await api.setBudgetCarryover(month, categoryId, true);

const budgetMonth = await api.getBudgetMonth(month);
expect(budgetMonth.categoryGroups).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: groupId,
categories: expect.arrayContaining([
expect.objectContaining({
id: categoryId,
budgeted: 100,
carryover: true,
}),
]),
}),
]),
);
});

//apis: createAccount, getAccounts, updateAccount, closeAccount, deleteAccount, reopenAccount
test('Accounts: successfully complete account operators', async () => {
const accountId1 = await api.createAccount(
{ name: 'test-account1', offbudget: true },
1000,
);
const accountId2 = await api.createAccount({ name: 'test-account2' }, 0);
let accounts = await api.getAccounts();

// accounts successfully created
expect(accounts).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: accountId1,
name: 'test-account1',
offbudget: true,
}),
expect.objectContaining({ id: accountId2, name: 'test-account2' }),
]),
);

await api.updateAccount(accountId1, { offbudget: false });
await api.closeAccount(accountId1, accountId2, null);
await api.deleteAccount(accountId2);

// accounts successfully updated, and one of them deleted
accounts = await api.getAccounts();
expect(accounts).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: accountId1,
name: 'test-account1',
closed: true,
offbudget: false,
}),
expect.not.objectContaining({ id: accountId2 }),
]),
);

await api.reopenAccount(accountId1);

// the non-deleted account is reopened
accounts = await api.getAccounts();
expect(accounts).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: accountId1,
name: 'test-account1',
closed: false,
}),
]),
);
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/desktop-client/src/components/AnimatedRefresh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type CSSProperties } from '../style';

import View from './common/View';

let spin = keyframes({
const spin = keyframes({
'0%': { transform: 'rotateZ(0deg)' },
'100%': { transform: 'rotateZ(360deg)' },
});
Expand Down
10 changes: 5 additions & 5 deletions packages/desktop-client/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function App({
// don't block on this in case they are offline or something)
send('get-remote-files').then(files => {
if (files) {
let remoteFile = files.find(f => f.fileId === cloudFileId);
const remoteFile = files.find(f => f.fileId === cloudFileId);
if (remoteFile && remoteFile.deleted) {
closeBudget();
}
Expand Down Expand Up @@ -122,14 +122,14 @@ function ErrorFallback({ error }: FallbackProps) {
}

function AppWrapper() {
let budgetId = useSelector(
const budgetId = useSelector(
state => state.prefs.local && state.prefs.local.id,
);
let cloudFileId = useSelector(
const cloudFileId = useSelector(
state => state.prefs.local && state.prefs.local.cloudFileId,
);
let loadingText = useSelector(state => state.app.loadingText);
let { loadBudget, closeBudget, loadGlobalPrefs, sync } = useActions();
const loadingText = useSelector(state => state.app.loadingText);
const { loadBudget, closeBudget, loadGlobalPrefs, sync } = useActions();
const [hiddenScrollbars, setHiddenScrollbars] = useState(
hasHiddenScrollbars(),
);
Expand Down
6 changes: 3 additions & 3 deletions packages/desktop-client/src/components/BackgroundImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import * as React from 'react';

import { theme } from '../style';

let linesTop = theme.pageBackgroundLineTop; // lines top
let linesMid = theme.pageBackgroundLineMid; // lines mid
let linesBottom = theme.pageBackgroundLineBottom; // lines bottom
const linesTop = theme.pageBackgroundLineTop; // lines top
const linesMid = theme.pageBackgroundLineMid; // lines mid
const linesBottom = theme.pageBackgroundLineBottom; // lines bottom

export function BackgroundImage() {
return (
Expand Down
4 changes: 2 additions & 2 deletions packages/desktop-client/src/components/BankSyncStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Text from './common/Text';
import View from './common/View';

export default function BankSyncStatus() {
let accountsSyncing = useSelector(state => state.account.accountsSyncing);
const accountsSyncing = useSelector(state => state.account.accountsSyncing);

let name = accountsSyncing
const name = accountsSyncing
? accountsSyncing === '__all'
? 'accounts'
: accountsSyncing
Expand Down
6 changes: 3 additions & 3 deletions packages/desktop-client/src/components/FatalError.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ function RenderUIError() {
}

function SharedArrayBufferOverride() {
let [expanded, setExpanded] = useState(false);
let [understand, setUnderstand] = useState(false);
const [expanded, setExpanded] = useState(false);
const [understand, setUnderstand] = useState(false);

return expanded ? (
<>
Expand Down Expand Up @@ -152,7 +152,7 @@ function SharedArrayBufferOverride() {
}

function FatalError({ buttonText, error }: FatalErrorProps) {
let [showError, setShowError] = useState(false);
const [showError, setShowError] = useState(false);

const showSimpleRender = 'type' in error && error.type === 'app-init-failure';

Expand Down
Loading

0 comments on commit 5bea94e

Please sign in to comment.