Skip to content

Commit 8595a93

Browse files
test: increment coverage from SqliteTransform
1 parent 7e25dea commit 8595a93

File tree

2 files changed

+115
-7
lines changed

2 files changed

+115
-7
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ISqliteService } from "../../src/shared/infra/SqliteService";
2+
import { GeolocationResponseSqlite } from "../../src/types/GeolocationSqliteResponse";
3+
4+
export class SqliteInMemoryService implements ISqliteService {
5+
private database: GeolocationResponseSqlite[] = [];
6+
7+
async getLocation(ip: string): Promise<GeolocationResponseSqlite | null> {
8+
const data = this.database.find((db) => db.ip === ip);
9+
10+
if (!data) {
11+
return null;
12+
}
13+
14+
return data;
15+
}
16+
17+
close(): Promise<void> {
18+
throw new Error("Method not implemented.");
19+
}
20+
}

test/transfoms/SqliteTransform.test.ts

Lines changed: 95 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,53 @@ import "reflect-metadata";
33
import { IRedisService } from "../../src/services/RedisService";
44
import { DataSourceInput } from "../../src/types/DataSourceInput";
55
import { GeolocationOutput } from "../../src/types/GeolocationOutput";
6+
7+
import { getFilePath } from "../../src/utils/getFilePath";
8+
import { constants } from "../../src/app/constants/constants";
69
import { RedisInMemoryService } from "../services/RedisInMemoryService";
710
import { SqliteTransform } from "../../src/app/transforms/SqliteTranslator";
811

12+
import {
13+
ISqliteService,
14+
SqliteService,
15+
} from "../../src/shared/infra/SqliteService";
16+
import { SqliteInMemoryService } from "../services/SqliteInMemoryService";
17+
import { GeolocationResponseSqlite } from "../../src/types/GeolocationSqliteResponse";
18+
919
describe("[SqliteTransform]", () => {
1020
let redisService: IRedisService;
21+
let sqliteService: ISqliteService;
22+
1123
let sqliteTransform: SqliteTransform;
1224

13-
let getLocationSpy: jest.SpyInstance;
14-
let setLocationSpy: jest.SpyInstance;
25+
let getLocationFromRedisSpy: jest.SpyInstance;
26+
let setLocationFromRedisSpy: jest.SpyInstance;
27+
28+
let getLocationFromSqliteSpy: jest.SpyInstance;
1529

1630
beforeAll(() => {
1731
redisService = new RedisInMemoryService();
18-
sqliteTransform = new SqliteTransform(redisService);
1932

20-
getLocationSpy = jest.spyOn(RedisInMemoryService.prototype, "getLocation");
21-
setLocationSpy = jest.spyOn(RedisInMemoryService.prototype, "setLocation");
33+
sqliteService = new SqliteService(
34+
getFilePath(constants.TRANSLATOR_PATH, "IPs.sqlite")
35+
);
36+
37+
sqliteTransform = new SqliteTransform(redisService, sqliteService);
38+
39+
getLocationFromSqliteSpy = jest.spyOn(
40+
SqliteInMemoryService.prototype,
41+
"getLocation"
42+
);
43+
44+
getLocationFromRedisSpy = jest.spyOn(
45+
RedisInMemoryService.prototype,
46+
"getLocation"
47+
);
48+
49+
setLocationFromRedisSpy = jest.spyOn(
50+
RedisInMemoryService.prototype,
51+
"setLocation"
52+
);
2253
});
2354

2455
describe("scenarios with geolocation already exists in cache", () => {
@@ -58,8 +89,65 @@ describe("[SqliteTransform]", () => {
5889
}
5990
});
6091

61-
expect(getLocationSpy).toHaveBeenCalledWith(chunk.ip);
62-
expect(setLocationSpy).not.toHaveBeenCalled();
92+
expect(getLocationFromRedisSpy).toHaveBeenCalledWith(chunk.ip);
93+
expect(setLocationFromRedisSpy).not.toHaveBeenCalled();
94+
});
95+
});
96+
97+
describe("scenarios without geolocation in cache", () => {
98+
const ip = "30.46.245.122";
99+
const clientId = "95cdb0f2-9487-5bfd-aeda-bac27dd406fa";
100+
const timestamp = new Date().getTime();
101+
102+
const chunk: DataSourceInput = {
103+
ip,
104+
clientId,
105+
timestamp,
106+
};
107+
108+
const geolocationResponseSqlite: GeolocationResponseSqlite = {
109+
ip: "30.46.245.122",
110+
city: "Columbus",
111+
state: "Ohio",
112+
longitude: -82.89573,
113+
latitude: 39.97883,
114+
country: "United States",
115+
};
116+
117+
const geolotionOutput: GeolocationOutput = {
118+
ip,
119+
clientId,
120+
timestamp,
121+
city: geolocationResponseSqlite.city,
122+
region: geolocationResponseSqlite.state,
123+
country: geolocationResponseSqlite.country,
124+
latitude: geolocationResponseSqlite.latitude,
125+
longitude: geolocationResponseSqlite.longitude,
126+
};
127+
128+
it("should parse data source data to geolocation output", async () => {
129+
setLocationFromRedisSpy.mockResolvedValueOnce(undefined);
130+
getLocationFromSqliteSpy.mockResolvedValueOnce(geolocationResponseSqlite);
131+
132+
await sqliteTransform._transform(chunk, "utf-8", (error) => {
133+
if (error) {
134+
console.error(error);
135+
}
136+
});
137+
138+
expect(getLocationFromRedisSpy).toHaveBeenCalledWith(chunk.ip);
139+
expect(setLocationFromRedisSpy).toHaveBeenCalledWith(geolotionOutput);
140+
});
141+
142+
it("should stop transform stream if sqlite return an error", async () => {
143+
getLocationFromSqliteSpy.mockRejectedValueOnce(null);
144+
145+
await sqliteTransform._transform(chunk, "utf-8", (error) => {
146+
expect(error).toBeInstanceOf(Error);
147+
expect(error).toEqual(
148+
new Error("An error occurred while reading the data from sqlite")
149+
);
150+
});
63151
});
64152
});
65153
});

0 commit comments

Comments
 (0)