Skip to content

Commit c94fe4b

Browse files
Added unit tests for store_individual_ip
1 parent d1cff60 commit c94fe4b

File tree

2 files changed

+187
-9
lines changed

2 files changed

+187
-9
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import 'mocha'
2+
import { assert, expect } from 'chai'
3+
4+
import { Pool } from 'pg'
5+
import sinon, { SinonMock, SinonStub } from 'sinon'
6+
import { PostgresStoreIndividualIP } from '../../source'
7+
import { Session } from '../../source/models/session'
8+
const session_handler = require('../../source/util/session_handler')
9+
const migration_handler = require('../../source/util/migration_handler')
10+
11+
class ClientMock {
12+
query() {}
13+
release() {}
14+
}
15+
16+
describe('Postgres Store Individual IP', () => {
17+
let query: SinonStub
18+
let connect: SinonStub
19+
let client: SinonMock
20+
let getSessionStub: SinonStub
21+
let applyMigrationsStub: SinonStub
22+
let isSessionValidSpy: SinonStub
23+
let newCreatedSession: Session
24+
25+
beforeEach(() => {
26+
query = sinon.stub(Pool.prototype, 'query')
27+
connect = sinon.stub(Pool.prototype, 'connect')
28+
client = sinon.mock(ClientMock.prototype)
29+
getSessionStub = sinon.stub(session_handler, 'getSession')
30+
isSessionValidSpy = sinon.stub(session_handler, 'isSessionValid')
31+
applyMigrationsStub = sinon.stub(migration_handler, 'applyMigrations')
32+
const futureTime = new Date()
33+
const timeOffset = 5000
34+
futureTime.setMilliseconds(futureTime.getMilliseconds() + timeOffset)
35+
36+
newCreatedSession = {
37+
id: '1',
38+
name: 'test-name',
39+
type: 'test-type',
40+
expires_at: futureTime,
41+
}
42+
})
43+
44+
afterEach(() => {
45+
query.restore() // reset stub/mock
46+
connect.restore()
47+
client.restore()
48+
getSessionStub.restore()
49+
applyMigrationsStub.restore()
50+
isSessionValidSpy.restore()
51+
})
52+
53+
it('constructor should call correct functions', async () => {
54+
new PostgresStoreIndividualIP({}, 'test')
55+
sinon.assert.callCount(applyMigrationsStub, 1)
56+
})
57+
58+
it('increment function should follow expected business logic', async () => {
59+
let pool = new Pool()
60+
61+
isSessionValidSpy.returns(true)
62+
query.onFirstCall().returns({
63+
rows: [],
64+
})
65+
66+
query.onSecondCall().returns({
67+
rows: [
68+
{
69+
count: 1,
70+
},
71+
],
72+
})
73+
let testStore = new PostgresStoreIndividualIP({}, 'test')
74+
testStore.pool = pool
75+
testStore.session = newCreatedSession
76+
77+
await testStore.increment('key')
78+
sinon.assert.callCount(isSessionValidSpy, 1)
79+
sinon.assert.calledWith(
80+
query,
81+
'INSERT INTO rate_limit.individual_records(key, session_id) VALUES ($1, $2)',
82+
['key', newCreatedSession.id],
83+
)
84+
sinon.assert.calledWith(
85+
query,
86+
'SELECT count(id) AS count FROM rate_limit.individual_records WHERE key = $1 AND session_id = $2',
87+
['key', newCreatedSession.id],
88+
)
89+
})
90+
91+
it('decrement function should follow expected business logic', async () => {
92+
let pool = new Pool()
93+
query.onFirstCall().returns({
94+
rows: [],
95+
})
96+
97+
query.onSecondCall().returns({
98+
rows: [
99+
{
100+
count: 1,
101+
},
102+
],
103+
})
104+
let testStore = new PostgresStoreIndividualIP({}, 'test')
105+
testStore.pool = pool
106+
testStore.session = newCreatedSession
107+
108+
await testStore.decrement('key')
109+
let decrementQuery = `
110+
WITH
111+
rows_to_delete AS (
112+
SELECT id FROM rate_limit.individual_records
113+
WHERE key = $1 and session_id = $2 ORDER BY registered_at LIMIT 1
114+
)
115+
DELETE FROM rate_limit.individual_records
116+
USING rows_to_delete WHERE individual_records.id = rows_to_delete.id
117+
`
118+
sinon.assert.calledWith(query, decrementQuery, [
119+
'key',
120+
newCreatedSession.id,
121+
])
122+
})
123+
124+
it('resetKey function should follow expected business logic', async () => {
125+
let pool = new Pool()
126+
query.onFirstCall().returns({
127+
rows: [],
128+
})
129+
130+
query.onSecondCall().returns({
131+
rows: [
132+
{
133+
count: 1,
134+
},
135+
],
136+
})
137+
let testStore = new PostgresStoreIndividualIP({}, 'test')
138+
testStore.pool = pool
139+
testStore.session = newCreatedSession
140+
141+
await testStore.resetKey('key')
142+
let resetQuery = `
143+
DELETE FROM rate_limit.individual_records
144+
WHERE key = $1 AND session_id = $2
145+
`
146+
sinon.assert.calledWith(query, resetQuery, ['key', newCreatedSession.id])
147+
})
148+
149+
it('resetAll function should follow expected business logic', async () => {
150+
let pool = new Pool()
151+
query.onFirstCall().returns({
152+
rows: [],
153+
})
154+
155+
query.onSecondCall().returns({
156+
rows: [
157+
{
158+
count: 1,
159+
},
160+
],
161+
})
162+
let testStore = new PostgresStoreIndividualIP({}, 'test')
163+
testStore.pool = pool
164+
testStore.session = newCreatedSession
165+
166+
await testStore.resetAll()
167+
let resetAllQuery = `
168+
DELETE FROM rate_limit.individual_records WHERE session_id = $1
169+
`
170+
sinon.assert.calledWith(query, resetAllQuery, [newCreatedSession.id])
171+
})
172+
})

test/util/session_handler.spec.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ describe('Session Handling - Database Interaction', () => {
122122
assert.equal(databaseSession.id, notExpiredSession.id)
123123
assert.equal(databaseSession.type, notExpiredSession.type)
124124
assert.equal(databaseSession.name, notExpiredSession.name)
125-
assert.equal(
126-
databaseSession.expires_at?.getSeconds(),
127-
notExpiredSession.expires_at.getSeconds(),
125+
assert.isTrue(
126+
(databaseSession.expires_at?.getMilliseconds() ||
127+
new Date().getMilliseconds()) -
128+
notExpiredSession.expires_at?.getMilliseconds() <
129+
10,
128130
)
129131
sinon.assert.callCount(query, 1)
130132
})
@@ -177,9 +179,11 @@ describe('Session Handling - Database Interaction', () => {
177179
assert.equal(databaseSession.id, newCreatedSession.id)
178180
assert.equal(databaseSession.type, newCreatedSession.type)
179181
assert.equal(databaseSession.name, newCreatedSession.name)
180-
assert.equal(
181-
databaseSession.expires_at?.getSeconds(),
182-
newCreatedSession.expires_at.getSeconds(),
182+
assert.isTrue(
183+
(databaseSession.expires_at?.getMilliseconds() ||
184+
new Date().getMilliseconds()) -
185+
newCreatedSession.expires_at?.getMilliseconds() <
186+
10,
183187
)
184188
sinon.assert.callCount(query, 3)
185189
})
@@ -248,9 +252,11 @@ describe('Session Handling - Database Interaction', () => {
248252
assert.equal(databaseSession.id, newCreatedSession.id)
249253
assert.equal(databaseSession.type, newCreatedSession.type)
250254
assert.equal(databaseSession.name, newCreatedSession.name)
251-
assert.equal(
252-
databaseSession.expires_at?.getSeconds(),
253-
newCreatedSession.expires_at.getSeconds(),
255+
assert.isTrue(
256+
(databaseSession.expires_at?.getMilliseconds() ||
257+
new Date().getMilliseconds()) -
258+
newCreatedSession.expires_at?.getMilliseconds() <
259+
10,
254260
)
255261
sinon.assert.callCount(query, 3)
256262
})

0 commit comments

Comments
 (0)