laplace-api 3.1.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +37 -0
- package/.github/workflows/test.yml +25 -0
- package/README.md +461 -2
- package/package.json +1 -1
- package/src/client/broker.ts +79 -99
- package/src/client/capital_increase.ts +17 -22
- package/src/client/collections.ts +61 -40
- package/src/client/financial_fundamentals.ts +40 -35
- package/src/client/financial_ratios.ts +168 -128
- package/src/client/funds.ts +139 -0
- package/src/client/key-insights.ts +17 -0
- package/src/client/live-price-web-socket.ts +84 -11
- package/src/client/live-price.ts +210 -58
- package/src/client/politician.ts +75 -0
- package/src/client/stocks.ts +85 -2
- package/src/test/broker.test.ts +581 -170
- package/src/test/capital_increase.test.ts +266 -15
- package/src/test/collections.test.ts +460 -17
- package/src/test/custom_theme.test.ts +256 -65
- package/src/test/financial_fundamentals.test.ts +301 -45
- package/src/test/financial_ratios.test.ts +376 -75
- package/src/test/funds.test.ts +317 -0
- package/src/test/helpers.ts +58 -0
- package/src/test/key-insight.test.ts +110 -0
- package/src/test/live-price.test.ts +427 -67
- package/src/test/politician.test.ts +253 -0
- package/src/test/readme.test.ts +483 -0
- package/src/test/search.test.ts +308 -23
- package/src/test/stocks.test.ts +800 -70
- package/src/utilities/configuration.ts +23 -10
- package/src/utilities/test.env +2 -2
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { Logger } from "winston";
|
|
2
|
+
import { LaplaceConfiguration } from "../utilities/configuration";
|
|
3
|
+
import "./client_test_suite";
|
|
4
|
+
import { Holding, Politician, PoliticianClient, PoliticianDetail, TopHolding } from "../client/politician";
|
|
5
|
+
|
|
6
|
+
describe("Politician", () => {
|
|
7
|
+
let politicianClient: PoliticianClient;
|
|
8
|
+
|
|
9
|
+
const mockPoliticians: Politician[] = [
|
|
10
|
+
{
|
|
11
|
+
id: 1,
|
|
12
|
+
politicianName: "John Doe",
|
|
13
|
+
totalHoldings: 10000,
|
|
14
|
+
lastUpdated: new Date("2024-01-01")
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 2,
|
|
18
|
+
politicianName: "Jane Smith",
|
|
19
|
+
totalHoldings: 10000,
|
|
20
|
+
lastUpdated: new Date("2024-01-02")
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const mockHoldings: Holding[] = [
|
|
25
|
+
{
|
|
26
|
+
politicianName: "John Doe",
|
|
27
|
+
symbol: "AAPL",
|
|
28
|
+
company: "Apple Inc.",
|
|
29
|
+
holding: "$500,000",
|
|
30
|
+
allocation: "50%",
|
|
31
|
+
lastUpdated: new Date("2024-01-01")
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
politicianName: "John Doe",
|
|
35
|
+
symbol: "GOOGL",
|
|
36
|
+
company: "Alphabet Inc.",
|
|
37
|
+
holding: "$500,000",
|
|
38
|
+
allocation: "50%",
|
|
39
|
+
lastUpdated: new Date("2024-01-01")
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const mockTopHoldings: TopHolding[] = [
|
|
44
|
+
{
|
|
45
|
+
symbol: "AAPL",
|
|
46
|
+
company: "Apple Inc.",
|
|
47
|
+
politicians: [
|
|
48
|
+
{
|
|
49
|
+
name: "John Doe",
|
|
50
|
+
holding: "$500,000",
|
|
51
|
+
allocation: "50%"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Jane Smith",
|
|
55
|
+
holding: "$1,000,000",
|
|
56
|
+
allocation: "40%"
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
count: 2
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const mockPoliticianPortfolio: PoliticianDetail = {
|
|
64
|
+
id: 1,
|
|
65
|
+
name: "John Doe",
|
|
66
|
+
holdings: [
|
|
67
|
+
{
|
|
68
|
+
symbol: "AAPL",
|
|
69
|
+
company: "Apple Inc.",
|
|
70
|
+
holding: "$500,000",
|
|
71
|
+
allocation: "50%"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
symbol: "GOOGL",
|
|
75
|
+
company: "Alphabet Inc.",
|
|
76
|
+
holding: "$500,000",
|
|
77
|
+
allocation: "50%"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
totalHoldings: 1000000,
|
|
81
|
+
lastUpdated: new Date("2024-01-01")
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
beforeAll(async () => {
|
|
85
|
+
const config = (global as any).testSuite.config as LaplaceConfiguration;
|
|
86
|
+
const logger: Logger = {
|
|
87
|
+
info: jest.fn(),
|
|
88
|
+
error: jest.fn(),
|
|
89
|
+
warn: jest.fn(),
|
|
90
|
+
debug: jest.fn(),
|
|
91
|
+
} as unknown as Logger;
|
|
92
|
+
|
|
93
|
+
politicianClient = new PoliticianClient(config, logger);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("Integration Tests", () => {
|
|
97
|
+
describe("getAllPolitician", () => {
|
|
98
|
+
it("should fetch all politicians", async () => {
|
|
99
|
+
const politicians = await politicianClient.getAllPolitician();
|
|
100
|
+
expect(Array.isArray(politicians)).toBe(true);
|
|
101
|
+
if (politicians.length > 0) {
|
|
102
|
+
expect(politicians[0]).toHaveProperty("id");
|
|
103
|
+
expect(politicians[0]).toHaveProperty("politicianName");
|
|
104
|
+
expect(politicians[0]).toHaveProperty("totalHoldings");
|
|
105
|
+
expect(politicians[0]).toHaveProperty("lastUpdated");
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe("getPoliticianHoldingBySymbol", () => {
|
|
111
|
+
it("should fetch holdings for a specific symbol", async () => {
|
|
112
|
+
const symbol = "AAPL";
|
|
113
|
+
const holdings = await politicianClient.getPoliticianHoldingBySymbol(symbol);
|
|
114
|
+
expect(Array.isArray(holdings)).toBe(true);
|
|
115
|
+
if (holdings.length > 0) {
|
|
116
|
+
expect(holdings[0]).toHaveProperty("politicianName");
|
|
117
|
+
expect(holdings[0]).toHaveProperty("symbol", symbol);
|
|
118
|
+
expect(holdings[0]).toHaveProperty("company");
|
|
119
|
+
expect(holdings[0]).toHaveProperty("holding");
|
|
120
|
+
expect(holdings[0]).toHaveProperty("allocation");
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe("getAllTopHoldings", () => {
|
|
126
|
+
it("should fetch all top holdings", async () => {
|
|
127
|
+
const topHoldings = await politicianClient.getAllTopHoldings();
|
|
128
|
+
expect(Array.isArray(topHoldings)).toBe(true);
|
|
129
|
+
if (topHoldings.length > 0) {
|
|
130
|
+
expect(topHoldings[0]).toHaveProperty("symbol");
|
|
131
|
+
expect(topHoldings[0]).toHaveProperty("company");
|
|
132
|
+
expect(topHoldings[0]).toHaveProperty("politicians");
|
|
133
|
+
expect(topHoldings[0]).toHaveProperty("count");
|
|
134
|
+
if (topHoldings[0].politicians.length > 0) {
|
|
135
|
+
expect(topHoldings[0].politicians[0]).toHaveProperty("name");
|
|
136
|
+
expect(topHoldings[0].politicians[0]).toHaveProperty("holding");
|
|
137
|
+
expect(topHoldings[0].politicians[0]).toHaveProperty("allocation");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("getPoliticianById", () => {
|
|
144
|
+
it("should fetch politician detail by ID", async () => {
|
|
145
|
+
const portfolio = await politicianClient.getPoliticianDetail(1);
|
|
146
|
+
expect(portfolio).toHaveProperty("id");
|
|
147
|
+
expect(portfolio).toHaveProperty("name");
|
|
148
|
+
expect(portfolio).toHaveProperty("holdings");
|
|
149
|
+
expect(portfolio).toHaveProperty("totalHoldings");
|
|
150
|
+
expect(portfolio).toHaveProperty("lastUpdated");
|
|
151
|
+
if (portfolio.holdings.length > 0) {
|
|
152
|
+
expect(portfolio.holdings[0]).toHaveProperty("symbol");
|
|
153
|
+
expect(portfolio.holdings[0]).toHaveProperty("company");
|
|
154
|
+
expect(portfolio.holdings[0]).toHaveProperty("holding");
|
|
155
|
+
expect(portfolio.holdings[0]).toHaveProperty("allocation");
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("Mock Tests", () => {
|
|
162
|
+
beforeEach(() => {
|
|
163
|
+
jest.clearAllMocks();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("getAllPolitician", () => {
|
|
167
|
+
it("should return all politicians successfully", async () => {
|
|
168
|
+
jest.spyOn(politicianClient, "getAllPolitician").mockResolvedValue(mockPoliticians);
|
|
169
|
+
|
|
170
|
+
const result = await politicianClient.getAllPolitician();
|
|
171
|
+
|
|
172
|
+
expect(result).toEqual(mockPoliticians);
|
|
173
|
+
expect(result).toHaveLength(2);
|
|
174
|
+
expect(result[0].politicianName).toBe("John Doe");
|
|
175
|
+
expect(result[1].politicianName).toBe("Jane Smith");
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("should handle errors when fetching politicians", async () => {
|
|
179
|
+
jest.spyOn(politicianClient, "getAllPolitician").mockRejectedValue(new Error("Failed to fetch politicians"));
|
|
180
|
+
|
|
181
|
+
await expect(politicianClient.getAllPolitician()).rejects.toThrow("Failed to fetch politicians");
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("getPoliticianHoldingBySymbol", () => {
|
|
186
|
+
it("should return holdings for a symbol successfully", async () => {
|
|
187
|
+
jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockResolvedValue(mockHoldings);
|
|
188
|
+
|
|
189
|
+
const result = await politicianClient.getPoliticianHoldingBySymbol("AAPL");
|
|
190
|
+
|
|
191
|
+
expect(result).toEqual(mockHoldings);
|
|
192
|
+
expect(result).toHaveLength(2);
|
|
193
|
+
expect(result[0].symbol).toBe("AAPL");
|
|
194
|
+
expect(result[1].symbol).toBe("GOOGL");
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("should handle errors when fetching holdings", async () => {
|
|
198
|
+
jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockRejectedValue(new Error("Failed to fetch holdings"));
|
|
199
|
+
|
|
200
|
+
await expect(politicianClient.getPoliticianHoldingBySymbol("INVALID")).rejects.toThrow("Failed to fetch holdings");
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("should handle empty holdings", async () => {
|
|
204
|
+
jest.spyOn(politicianClient, "getPoliticianHoldingBySymbol").mockResolvedValue([]);
|
|
205
|
+
|
|
206
|
+
const result = await politicianClient.getPoliticianHoldingBySymbol("NONEXISTENT");
|
|
207
|
+
|
|
208
|
+
expect(result).toEqual([]);
|
|
209
|
+
expect(result).toHaveLength(0);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe("getAllTopHoldings", () => {
|
|
214
|
+
it("should return top holdings successfully", async () => {
|
|
215
|
+
jest.spyOn(politicianClient, "getAllTopHoldings").mockResolvedValue(mockTopHoldings);
|
|
216
|
+
|
|
217
|
+
const result = await politicianClient.getAllTopHoldings();
|
|
218
|
+
|
|
219
|
+
expect(result).toEqual(mockTopHoldings);
|
|
220
|
+
expect(result).toHaveLength(1);
|
|
221
|
+
expect(result[0].symbol).toBe("AAPL");
|
|
222
|
+
expect(result[0].politicians).toHaveLength(2);
|
|
223
|
+
expect(result[0].count).toBe(2);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("should handle errors when fetching top holdings", async () => {
|
|
227
|
+
jest.spyOn(politicianClient, "getAllTopHoldings").mockRejectedValue(new Error("Failed to fetch top holdings"));
|
|
228
|
+
|
|
229
|
+
await expect(politicianClient.getAllTopHoldings()).rejects.toThrow("Failed to fetch top holdings");
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe("getPoliticianDetail", () => {
|
|
234
|
+
it("should return politician by ID successfully", async () => {
|
|
235
|
+
jest.spyOn(politicianClient, "getPoliticianDetail").mockResolvedValue(mockPoliticianPortfolio);
|
|
236
|
+
|
|
237
|
+
const result = await politicianClient.getPoliticianDetail(1);
|
|
238
|
+
|
|
239
|
+
expect(result).toEqual(mockPoliticianPortfolio);
|
|
240
|
+
expect(result.id).toBe(1);
|
|
241
|
+
expect(result.name).toBe("John Doe");
|
|
242
|
+
expect(result.holdings).toHaveLength(2);
|
|
243
|
+
expect(result.totalHoldings).toBe(1000000);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it("should handle errors when fetching politician by ID", async () => {
|
|
247
|
+
jest.spyOn(politicianClient, "getPoliticianDetail").mockRejectedValue(new Error("Failed to fetch politician"));
|
|
248
|
+
|
|
249
|
+
await expect(politicianClient.getPoliticianDetail(999)).rejects.toThrow("Failed to fetch politician");
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|