Skip to content

Commit 811efac

Browse files
authored
[INS 329] Create tests for organizations dependency (#140)
Signed-off-by: Raúl Santos <4837+borfast@users.noreply.github.com>
1 parent 6c9d27e commit 811efac

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import {
2+
describe, test, expect, vi, beforeEach
3+
} from 'vitest';
4+
import {DateTime} from "luxon";
5+
import {mockTimeseries} from '../../mocks/tinybird-organizations-dependency-response.mock';
6+
import {
7+
mockTimeseries as mockLeaderboardTimeseries
8+
} from '../../mocks/tinybird-organizations-leaderboard-response.mock';
9+
import type {OrganizationDependencyResponse} from "~~/server/data/tinybird/organizations-dependency-data-source";
10+
11+
const mockFetchFromTinybird = vi.fn();
12+
13+
describe('Organizations Dependency Data Source', () => {
14+
beforeEach(() => {
15+
mockFetchFromTinybird.mockClear();
16+
17+
// Here be dragons! vi.doMock is not hoisted, and thus it is executed after the original import statement.
18+
// This means that the import for tinybird.ts inside active-organizations-data-source.ts would still be used,
19+
// and thus not mocked. This means we need to import the module again after the mock is set, whenever we want to
20+
// use it.
21+
vi.doMock(import("./tinybird"), () => ({
22+
fetchFromTinybird: mockFetchFromTinybird,
23+
}));
24+
})
25+
26+
test('should fetch organizations dependency data with correct parameters', async () => {
27+
// We have to import this here again because vi.doMock is not hoisted. See the explanation in beforeEach().
28+
const {fetchOrganizationDependency} = await import("~~/server/data/tinybird/organizations-dependency-data-source");
29+
30+
mockFetchFromTinybird.mockResolvedValueOnce(mockTimeseries).mockResolvedValueOnce(mockLeaderboardTimeseries);
31+
32+
const startDate = DateTime.utc(2024, 3, 20);
33+
const endDate = DateTime.utc(2025, 3, 20);
34+
35+
const filter = {
36+
project: 'the-linux-kernel-organization',
37+
startDate,
38+
endDate
39+
};
40+
41+
const result = await fetchOrganizationDependency(filter);
42+
43+
expect(mockFetchFromTinybird).toHaveBeenNthCalledWith(
44+
1,
45+
'/v0/pipes/organization_dependency.json',
46+
filter
47+
)
48+
expect(mockFetchFromTinybird).toHaveBeenNthCalledWith(
49+
2,
50+
'/v0/pipes/organizations_leaderboard.json',
51+
{
52+
...filter,
53+
limit: 5
54+
}
55+
);
56+
57+
const topOrganizationsCount = mockTimeseries.data.length;
58+
const lastOrganization = mockTimeseries.data.at(-1);
59+
const topOrganizationsPercentage = lastOrganization?.contributionPercentageRunningTotal || 0;
60+
const totalOrganizationCount = mockTimeseries.data[0]?.totalOrganizationCount || 0;
61+
62+
const expectedResult: OrganizationDependencyResponse = {
63+
topOrganizations: {
64+
count: topOrganizationsCount,
65+
percentage: topOrganizationsPercentage
66+
},
67+
otherOrganizations: {
68+
count: Math.max(0, (totalOrganizationCount || 0) - topOrganizationsCount),
69+
percentage: 100 - topOrganizationsPercentage
70+
},
71+
list: mockLeaderboardTimeseries.data.map((item) => ({
72+
logo: item.logo,
73+
name: item.displayName,
74+
contributions: item.contributionCount,
75+
percentage: item.contributionPercentage,
76+
website: ''
77+
}))
78+
};
79+
80+
expect(result).toEqual(expectedResult);
81+
});
82+
83+
// TODO: Add checks for invalid dates, invalid data, sql injections, and other edge cases.
84+
});
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// https://api.us-west-2.aws.tinybird.co/v0/pipes/organization_dependency.json?startDate=2024-03-20 00:00:00&endDate=2025-03-20 00:00:00&project=the-linux-kernel-organization
2+
3+
export const mockTimeseries = {
4+
meta: [
5+
{
6+
name: "id",
7+
type: "String"
8+
},
9+
{
10+
name: "displayName",
11+
type: "String"
12+
},
13+
{
14+
name: "contributionPercentage",
15+
type: "Float64"
16+
},
17+
{
18+
name: "contributionPercentageRunningTotal",
19+
type: "Float64"
20+
},
21+
{
22+
name: "totalOrganizationCount",
23+
type: "UInt64"
24+
}
25+
],
26+
data: [
27+
{
28+
id: "d7bf07d9-780b-4279-bfbc-d83f85950353",
29+
displayName: "Red Hat, Inc.",
30+
contributionPercentage: 13,
31+
contributionPercentageRunningTotal: 13,
32+
totalOrganizationCount: 952
33+
},
34+
{
35+
id: "9f7f73b0-95d6-49c2-bffe-8300c03852ef",
36+
displayName: "Linaro Limited",
37+
contributionPercentage: 10,
38+
contributionPercentageRunningTotal: 23,
39+
totalOrganizationCount: 952
40+
},
41+
{
42+
id: "0c562f29-ab29-4383-b4ca-85457367ee39",
43+
displayName: "Arm Limited",
44+
contributionPercentage: 7,
45+
contributionPercentageRunningTotal: 30,
46+
totalOrganizationCount: 952
47+
},
48+
{
49+
id: "987a49ec-31c9-4611-a5f0-a0ce52a999b2",
50+
displayName: "SUSE",
51+
contributionPercentage: 7,
52+
contributionPercentageRunningTotal: 37,
53+
totalOrganizationCount: 952
54+
},
55+
{
56+
id: "543dd100-3a92-4a9d-ba5a-d629f452681a",
57+
displayName: "Advanced Micro Devices (AMD)",
58+
contributionPercentage: 6,
59+
contributionPercentageRunningTotal: 43,
60+
totalOrganizationCount: 952
61+
},
62+
{
63+
id: "51fde723-67df-4e0e-91c6-936d01d59559",
64+
displayName: "The Linux Foundation",
65+
contributionPercentage: 5,
66+
contributionPercentageRunningTotal: 48,
67+
totalOrganizationCount: 952
68+
},
69+
{
70+
id: "522278e4-d0dc-4ddb-a7bc-739253b760cf",
71+
displayName: "Qualcomm, Inc.",
72+
contributionPercentage: 3,
73+
contributionPercentageRunningTotal: 51,
74+
totalOrganizationCount: 952
75+
}
76+
],
77+
rows: 7,
78+
rows_before_limit_at_least: 926,
79+
statistics: {
80+
elapsed: 0.840925162,
81+
rows_read: 1345215,
82+
bytes_read: 140177381
83+
}
84+
};

0 commit comments

Comments
 (0)