Skip to content

Commit

Permalink
Merge branch 'master' into feature/support-system-theme
Browse files Browse the repository at this point in the history
  • Loading branch information
spezzino committed Dec 7, 2023
2 parents b24939d + 2741422 commit d39ff69
Show file tree
Hide file tree
Showing 337 changed files with 4,403 additions and 3,860 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
1 change: 1 addition & 0 deletions packages/api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ app/bundle.api.js*
app/stats.json
migrations
default-db.sqlite
mocks/budgets/**/*
21 changes: 21 additions & 0 deletions packages/api/__snapshots__/methods.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`API setup and teardown successfully loads budget 1`] = `
Array [
"2016-10",
"2016-11",
"2016-12",
"2017-01",
"2017-02",
"2017-03",
"2017-04",
"2017-05",
"2017-06",
"2017-07",
"2017-08",
"2017-09",
"2017-10",
"2017-11",
"2017-12",
]
`;
5 changes: 3 additions & 2 deletions packages/api/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable import/no-unused-modules */

// eslint-disable-next-line import/extensions
import * as bundle from './app/bundle.api.js';
import * as injected from './injected';
import { validateNodeVersion } from './validateNodeVersion';

let actualApp;
export const internal = bundle.lib;
Expand All @@ -18,6 +17,8 @@ export async function init(config = {}) {
return;
}

validateNodeVersion();

global.fetch = (...args) =>
import('node-fetch').then(({ default: fetch }) => fetch(...args));

Expand Down
24 changes: 24 additions & 0 deletions packages/api/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
moduleFileExtensions: [
'testing.js',
'testing.ts',
'api.js',
'api.ts',
'api.tsx',
'electron.js',
'electron.ts',
'mjs',
'js',
'ts',
'tsx',
'json',
],
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/'],
watchPathIgnorePatterns: ['<rootDir>/mocks/budgets/'],
setupFilesAfterEnv: ['<rootDir>/../loot-core/src/mocks/setup.ts'],
transformIgnorePatterns: ['/node_modules/'],
transform: {
'^.+\\.(t|j)sx?$': '@swc/jest',
},
};
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,
}),
]),
);
});
});
Empty file.
10 changes: 8 additions & 2 deletions packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@actual-app/api",
"version": "6.2.1",
"version": "6.3.0",
"license": "MIT",
"description": "An API for Actual",
"engines": {
Expand All @@ -16,15 +16,21 @@
"build:node": "tsc --p tsconfig.dist.json",
"build:migrations": "cp migrations/*.sql dist/migrations",
"build:default-db": "cp default-db.sqlite dist/",
"build": "rm -rf dist && yarn run build:app && yarn run build:node && yarn run build:migrations && yarn run build:default-db"
"build": "rm -rf dist && yarn run build:app && yarn run build:node && yarn run build:migrations && yarn run build:default-db",
"test": "yarn run build:app && jest -c jest.config.js"
},
"dependencies": {
"better-sqlite3": "^9.1.1",
"compare-versions": "^6.1.0",
"node-fetch": "^3.3.2",
"uuid": "^9.0.0"
},
"devDependencies": {
"@swc/core": "^1.3.82",
"@swc/jest": "^0.2.29",
"@types/jest": "^27.5.0",
"@types/uuid": "^9.0.2",
"jest": "^27.0.0",
"typescript": "^5.0.2"
}
}
Loading

0 comments on commit d39ff69

Please sign in to comment.