-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
545 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Transaction Time (CET),Transaction Category,Transaction Type,Asset Id,Asset Name,Asset Currency,Transaction Currency,Currency Pair,Exchange Rate,Transaction Amount,Trade Amount,Trade Price,Trade Quantity,Cash Balance Amount,Profit And Loss Amount,Profit And Loss Currency | ||
2020-11-18 12:15:23.606000,deposits,Sepa Deposit,,,,EUR,,,500,,,,500,, | ||
2020-11-18 13:02:54.696000,deposits,Sepa Deposit,,,,EUR,,,100,,,,600.03,, | ||
2023-03-21 13:37:29.383000,trades,Buy Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-542.92,542.92,11.08,49,48.49,, | ||
2023-03-21 13:37:29.384000,fees,Trading Fee,NL0011821202,ING,,EUR,,,-1.5,,,,46.99,, | ||
2023-03-21 13:37:29.384000,trades,Buy Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-7.08,7.0800092,11.08,0.638989,39.91,, | ||
2023-05-02 11:07:12.872000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,36.92,, | ||
2023-05-05 11:38:06.646000,dividends,Cash Dividend,NL0011821202,ING,EUR,EUR,EUREUR,1,16.4,,,,53.32,, | ||
2023-06-01 18:51:19.620000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,50.33,, | ||
2023-07-01 12:32:03.013000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,47.34,, | ||
2023-07-09 10:25:51.533000,interest,Interest Payment,,,,EUR,,,0.23,,,,47.57,, | ||
2023-08-01 16:19:45.363000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,44.58,, | ||
2023-08-14 16:37:01.245000,dividends,Cash Dividend,NL0011821202,ING,EUR,EUR,EUREUR,1,14.76,,,,59.34,, | ||
2023-09-01 18:28:48.386000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,56.35,, | ||
2023-10-01 16:20:38.540000,fees,Subscription Fee,,,,EUR,,,-2.99,,,,53.36,, | ||
2023-10-05 08:10:02.073000,interest,Interest Payment,,,,EUR,,,0.34,,,,53.7,, | ||
2023-11-05 07:05:37.311000,interest,Interest Payment,,,,EUR,,,0.11,,,,50.82,, | ||
2024-01-19 17:15:46.543000,deposits,Sepa Deposit,,,,EUR,,,10,,,,55.07,, | ||
2024-05-14 13:57:08.427000,withdrawals,Sepa Withdrawal,,,,EUR,,,-1200,,,,1293.6,, | ||
2023-03-21 13:37:29.384000,trades,Sell Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-7.08,7.0800092,11.08,0.638989,39.91,, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { SecurityService } from "../securityService"; | ||
import { AbstractConverter } from "./abstractconverter"; | ||
import YahooFinanceServiceMock from "../testing/yahooFinanceServiceMock"; | ||
|
||
// Create a test wrapper so the AbstractConverter can be tested. | ||
class TestAbstractConverter extends AbstractConverter { | ||
|
||
// This method is covered by other tests | ||
isIgnoredRecord(_: any): boolean { | ||
return false; | ||
} | ||
|
||
// This method is covered by other tests. | ||
processFileContents(_: string, successCallback: CallableFunction, __: CallableFunction): void { | ||
return successCallback(); | ||
} | ||
|
||
// Wrap processHeaders() so it can be tested. | ||
public processHeadersTest(csvFile: string, splitChar?: string): string[] { | ||
return this.processHeaders(csvFile, splitChar); | ||
} | ||
|
||
// Wrap logQueryError() so it can be tested. | ||
public logQueryErrorTest(query: string, index: number) { | ||
return this.logQueryError(query, index) | ||
} | ||
} | ||
|
||
describe("abstractConverter", () => { | ||
|
||
beforeEach(() => { | ||
jest.spyOn(console, "log").mockImplementation(jest.fn()); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("should construct", () => { | ||
|
||
// Act | ||
const sut = new TestAbstractConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
// Assert | ||
expect(sut).toBeTruthy(); | ||
}); | ||
|
||
it("processHeaders() should process headers", () => { | ||
|
||
// Arrange | ||
let tempFileContent = ""; | ||
tempFileContent += "Type,ISIN,PriceInEUR,PriceInCHF,TransactionTimeCET\n"; | ||
|
||
const sut = new TestAbstractConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
// Act | ||
const headers = sut.processHeadersTest(tempFileContent, ","); | ||
|
||
// Assert | ||
expect(headers.length).toBe(5); | ||
expect(headers[1]).toBe("isin"); | ||
expect(headers[2]).toBe("priceInEur"); | ||
expect(headers[3]).toBe("priceInChf"); | ||
expect(headers[4]).toBe("transactionTimeCet"); | ||
}); | ||
|
||
describe("logQueryError()", () => { | ||
it("should log a query if it was given", () => { | ||
// Arrange | ||
const sut = new TestAbstractConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
const consoleSpy = jest.spyOn(console, "log"); | ||
|
||
// Act | ||
sut.logQueryErrorTest("AAPL", 1); | ||
|
||
// Assert | ||
expect(consoleSpy).toHaveBeenCalledWith("\n[e] An error ocurred while trying to retrieve symbol AAPL (line 3)!\n"); | ||
}); | ||
}); | ||
|
||
it("should log without a query if it was not given", () => { | ||
// Arrange | ||
const sut = new TestAbstractConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
const consoleSpy = jest.spyOn(console, "log"); | ||
|
||
// Act | ||
sut.logQueryErrorTest(undefined, 2); | ||
|
||
// Assert | ||
expect(consoleSpy).toHaveBeenCalledWith("\n[e] An error ocurred while trying to retrieve an empty symbol (line 4)!\n"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { BuxConverter } from "./buxConverter"; | ||
import { SecurityService } from "../securityService"; | ||
import { GhostfolioExport } from "../models/ghostfolioExport"; | ||
import YahooFinanceServiceMock from "../testing/yahooFinanceServiceMock"; | ||
|
||
describe("buxConverter", () => { | ||
|
||
beforeEach(() => { | ||
jest.spyOn(console, "log").mockImplementation(jest.fn()); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("should construct", () => { | ||
|
||
// Act | ||
const sut = new BuxConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
// Assert | ||
expect(sut).toBeTruthy(); | ||
}); | ||
|
||
it("should process sample CSV file", (done) => { | ||
|
||
// Arange | ||
const sut = new BuxConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
const inputFile = "samples/bux-export.csv"; | ||
|
||
// Act | ||
sut.readAndProcessFile(inputFile, (actualExport: GhostfolioExport) => { | ||
|
||
// Assert | ||
expect(actualExport).toBeTruthy(); | ||
expect(actualExport.activities.length).toBeGreaterThan(0); | ||
expect(actualExport.activities.length).toBe(15); | ||
|
||
done(); | ||
}, () => { done.fail("Should not have an error!"); }); | ||
}); | ||
|
||
describe("should throw an error if", () => { | ||
it("the input file does not exist", (done) => { | ||
|
||
// Arrange | ||
const sut = new BuxConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
let tempFileName = "tmp/testinput/bux-filedoesnotexist.csv"; | ||
|
||
// Act | ||
sut.readAndProcessFile(tempFileName, () => { done.fail("Should not succeed!"); }, (err: Error) => { | ||
|
||
// Assert | ||
expect(err).toBeTruthy(); | ||
|
||
done(); | ||
}); | ||
}); | ||
|
||
it("the input file is empty", (done) => { | ||
|
||
// Arrange | ||
const sut = new BuxConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
let tempFileContent = ""; | ||
tempFileContent += `Transaction Time (CET),Transaction Category,Transaction Type,Asset Id,Asset Name,Asset Currency,Transaction Currency,Currency Pair,Exchange Rate,Transaction Amount,Trade Amount,Trade Price,Trade Quantity,Cash Balance Amount,Profit And Loss Amount,Profit And Loss Currency\n`; | ||
|
||
// Act | ||
sut.processFileContents(tempFileContent, () => { done.fail("Should not succeed!"); }, (err: Error) => { | ||
|
||
// Assert | ||
expect(err).toBeTruthy(); | ||
expect(err.message).toContain("An error ocurred while parsing"); | ||
|
||
done(); | ||
}); | ||
}); | ||
|
||
it("the header and row column count doesn't match", (done) => { | ||
|
||
// Arrange | ||
const sut = new BuxConverter(new SecurityService(new YahooFinanceServiceMock())); | ||
|
||
let tempFileContent = ""; | ||
tempFileContent += `Transaction Time (CET),Transaction Category,Transaction Type,Asset Id,Asset Name,Asset Currency,Transaction Currency,Currency Pair,Exchange Rate,Transaction Amount,Trade Amount,Trade Price,Trade Quantity,Cash Balance Amount,Profit And Loss Amount,Profit And Loss Currency\n`; | ||
tempFileContent += `2023-03-21 13:37:29.383000,trades,Buy Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-542.92,542.92,11.08,49,48.49,,,,`; | ||
|
||
// Act | ||
sut.processFileContents(tempFileContent, () => { done.fail("Should not succeed!"); }, (err: Error) => { | ||
|
||
// Assert | ||
expect(err).toBeTruthy(); | ||
expect(err.message).toBe("An error ocurred while parsing! Details: Invalid Record Length: columns length is 16, got 18 on line 2"); | ||
|
||
done(); | ||
}); | ||
}); | ||
|
||
it("Yahoo Finance throws an error", (done) => { | ||
|
||
// Arrange | ||
let tempFileContent = ""; | ||
tempFileContent += `Transaction Time (CET),Transaction Category,Transaction Type,Asset Id,Asset Name,Asset Currency,Transaction Currency,Currency Pair,Exchange Rate,Transaction Amount,Trade Amount,Trade Price,Trade Quantity,Cash Balance Amount,Profit And Loss Amount,Profit And Loss Currency\n`; | ||
tempFileContent += `2023-03-21 13:37:29.383000,trades,Buy Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-542.92,542.92,11.08,49,48.49,,`; | ||
|
||
// Mock Yahoo Finance service to throw error. | ||
const yahooFinanceServiceMock = new YahooFinanceServiceMock(); | ||
jest.spyOn(yahooFinanceServiceMock, "search").mockImplementation(() => { throw new Error("Unit test error"); }); | ||
const sut = new BuxConverter(new SecurityService(yahooFinanceServiceMock)); | ||
|
||
// Act | ||
sut.processFileContents(tempFileContent, () => { done.fail("Should not succeed!"); }, (err: Error) => { | ||
|
||
// Assert | ||
expect(err).toBeTruthy(); | ||
expect(err.message).toContain("Unit test error"); | ||
|
||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
it("should log when Yahoo Finance returns no symbol", (done) => { | ||
|
||
// Arrange | ||
let tempFileContent = ""; | ||
tempFileContent += `Transaction Time (CET),Transaction Category,Transaction Type,Asset Id,Asset Name,Asset Currency,Transaction Currency,Currency Pair,Exchange Rate,Transaction Amount,Trade Amount,Trade Price,Trade Quantity,Cash Balance Amount,Profit And Loss Amount,Profit And Loss Currency\n`; | ||
tempFileContent += `2023-03-21 13:37:29.383000,trades,Buy Trade,NL0011821202,ING,EUR,EUR,EUREUR,1,-542.92,542.92,11.08,49,48.49,,`; | ||
|
||
// Mock Yahoo Finance service to return no quotes. | ||
const yahooFinanceServiceMock = new YahooFinanceServiceMock(); | ||
jest.spyOn(yahooFinanceServiceMock, "search").mockImplementation(() => { return Promise.resolve({ quotes: [] }) }); | ||
const sut = new BuxConverter(new SecurityService(yahooFinanceServiceMock)); | ||
|
||
// Bit hacky, but it works. | ||
const consoleSpy = jest.spyOn((sut as any).progress, "log"); | ||
|
||
// Act | ||
sut.processFileContents(tempFileContent, () => { | ||
|
||
expect(consoleSpy).toHaveBeenCalledWith("[i] No result found for buy action for NL0011821202 with currency EUR! Please add this manually..\n"); | ||
|
||
done(); | ||
}, () => done.fail("Should not have an error!")); | ||
}); | ||
}); |
Oops, something went wrong.