lesgo 0.6.0 → 0.7.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/README.md +8 -2
- package/bin/lesgo-scripts.sh +2 -0
- package/package.json +8 -4
- package/src/middlewares/__tests__/errorHttpResponseMiddleware.spec.js +33 -16
- package/src/middlewares/__tests__/gzipHttpResponse.spec.js +6 -6
- package/src/middlewares/__tests__/normalizeHttpRequestMiddleware.spec.js +38 -0
- package/src/middlewares/__tests__/successHttpResponseMiddleware.spec.js +28 -12
- package/src/middlewares/errorHttpResponseMiddleware.js +10 -3
- package/src/middlewares/gzipHttpResponse.js +1 -1
- package/src/middlewares/normalizeHttpRequestMiddleware.js +21 -2
- package/src/middlewares/successHttpResponseMiddleware.js +9 -2
- package/src/middlewares/verifyJwtMiddleware.js +4 -2
- package/src/services/AuroraDbRDSProxyService.js +183 -0
- package/src/services/AuroraDbService.js +39 -5
- package/src/services/DynamoDbService.js +10 -8
- package/src/services/FirebaseAdminService.js +10 -7
- package/src/services/__tests__/AuroraDbRDSProxyService.spec.js +278 -0
- package/src/services/__tests__/AuroraDbService.spec.js +54 -0
- package/src/services/__tests__/LengthAwarePaginator.spec.js +180 -0
- package/src/services/__tests__/Paginator.spec.js +383 -0
- package/src/services/pagination/LengthAwarePaginator.js +49 -0
- package/src/services/pagination/Paginator.js +254 -0
- package/src/utils/__mocks__/db.js +109 -0
- package/src/utils/__tests__/db.spec.js +40 -1
- package/src/utils/__tests__/getJwtSubFromAuthHeader.spec.js +20 -0
- package/src/utils/__tests__/isDecimal.spec.js +12 -0
- package/src/utils/__tests__/isEmail.spec.js +28 -0
- package/src/utils/__tests__/prepSQLInsertParams.spec.js +46 -0
- package/src/utils/__tests__/prepSQLUpdateParams.spec.js +36 -0
- package/src/utils/__tests__/validateFields.spec.js +183 -0
- package/src/utils/db.js +13 -2
- package/src/utils/getJwtSubFromAuthHeader.js +18 -0
- package/src/utils/index.js +2 -0
- package/src/utils/isDecimal.js +2 -0
- package/src/utils/isEmail.js +15 -0
- package/src/utils/logger.js +1 -4
- package/src/utils/prepSQLInsertParams.js +21 -0
- package/src/utils/prepSQLUpdateParams.js +25 -0
- package/src/utils/validateFields.js +75 -0
|
@@ -23,6 +23,16 @@ describe('test AuroraDbService instantiate', () => {
|
|
|
23
23
|
expect(dataApiClient).toHaveBeenCalledWith(auroraConfig);
|
|
24
24
|
expect(db.client.mocked).toMatchObject(auroraConfig);
|
|
25
25
|
});
|
|
26
|
+
|
|
27
|
+
it('should not throw exception with custom region', () => {
|
|
28
|
+
const db = new AuroraDbService({
|
|
29
|
+
...auroraConfig,
|
|
30
|
+
region: 'ap-southeast-1',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(dataApiClient).toHaveBeenCalledWith(auroraConfig);
|
|
34
|
+
expect(db.client.mocked).toMatchObject(auroraConfig);
|
|
35
|
+
});
|
|
26
36
|
});
|
|
27
37
|
|
|
28
38
|
describe('test AuroraDbService connect', () => {
|
|
@@ -106,6 +116,50 @@ describe('test AuroraDbService select', () => {
|
|
|
106
116
|
});
|
|
107
117
|
});
|
|
108
118
|
|
|
119
|
+
describe('test AuroraDbService selectPaginate', () => {
|
|
120
|
+
it('should return paginated records when calling selectPaginate function', async () => {
|
|
121
|
+
const db = new AuroraDbService(auroraConfig);
|
|
122
|
+
return expect(db.selectPaginate('SELECT_QUERY', {})).resolves.toMatchObject(
|
|
123
|
+
{
|
|
124
|
+
count: 2,
|
|
125
|
+
previous_page: false,
|
|
126
|
+
current_page: 1,
|
|
127
|
+
next_page: false,
|
|
128
|
+
per_page: 10,
|
|
129
|
+
items: [
|
|
130
|
+
{
|
|
131
|
+
id: 1,
|
|
132
|
+
uid: 'some-uid-1',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 2,
|
|
136
|
+
uid: 'some-uid-2',
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should return paginated records when calling selectPaginate with defined total', async () => {
|
|
144
|
+
const db = new AuroraDbService(auroraConfig);
|
|
145
|
+
return expect(
|
|
146
|
+
db.selectPaginate('SELECT_QUERY', {}, 1, 2, 1)
|
|
147
|
+
).resolves.toMatchObject({
|
|
148
|
+
count: 1,
|
|
149
|
+
previous_page: 1,
|
|
150
|
+
current_page: 2,
|
|
151
|
+
next_page: 3,
|
|
152
|
+
per_page: 1,
|
|
153
|
+
items: [
|
|
154
|
+
{
|
|
155
|
+
id: 1,
|
|
156
|
+
uid: 'some-uid-1',
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
109
163
|
describe('test AuroraDbService selectFirst', () => {
|
|
110
164
|
it('should only return the first record when calling selectFirst', async () => {
|
|
111
165
|
const db = new AuroraDbService(auroraConfig);
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import LengthAwarePaginator from '../pagination/LengthAwarePaginator';
|
|
2
|
+
import {
|
|
3
|
+
mockData,
|
|
4
|
+
mockDataFirstItem,
|
|
5
|
+
mockDataLastItem,
|
|
6
|
+
} from '../../utils/__mocks__/db';
|
|
7
|
+
import db from '../../utils/db';
|
|
8
|
+
|
|
9
|
+
jest.mock('../../utils/db');
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
db.select.mockClear();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const FILE = 'Services/pagination/LengthAwarePaginator';
|
|
16
|
+
|
|
17
|
+
describe('test LengthAwarePaginator instantiate', () => {
|
|
18
|
+
it('should not throw exception when instantiating', async () => {
|
|
19
|
+
const paginator = new LengthAwarePaginator(
|
|
20
|
+
db,
|
|
21
|
+
'SELECT * FROM tests',
|
|
22
|
+
{},
|
|
23
|
+
{
|
|
24
|
+
perPage: 5,
|
|
25
|
+
total: 30,
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(await paginator.count()).toEqual(5);
|
|
30
|
+
expect(paginator.currentPage()).toEqual(1);
|
|
31
|
+
expect(await paginator.firstItem()).toMatchObject(mockDataFirstItem);
|
|
32
|
+
expect(await paginator.lastItem()).toMatchObject(mockDataLastItem);
|
|
33
|
+
expect(paginator.perPage()).toEqual(5);
|
|
34
|
+
expect(await paginator.total()).toEqual(30);
|
|
35
|
+
});
|
|
36
|
+
it('should not throw exception when instantiating with current page', async () => {
|
|
37
|
+
const paginator = new LengthAwarePaginator(
|
|
38
|
+
db,
|
|
39
|
+
'SELECT * FROM tests',
|
|
40
|
+
{},
|
|
41
|
+
{
|
|
42
|
+
perPage: 5,
|
|
43
|
+
currentPage: 2,
|
|
44
|
+
total: 30,
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(await paginator.count()).toEqual(5);
|
|
49
|
+
expect(paginator.currentPage()).toEqual(2);
|
|
50
|
+
expect(await paginator.firstItem()).toMatchObject(mockDataFirstItem);
|
|
51
|
+
expect(await paginator.lastItem()).toMatchObject(mockDataLastItem);
|
|
52
|
+
expect(paginator.perPage()).toEqual(5);
|
|
53
|
+
expect(await paginator.total()).toEqual(30);
|
|
54
|
+
});
|
|
55
|
+
it('should default perPage to 10 when instantiating without perPage', async () => {
|
|
56
|
+
const paginator = new LengthAwarePaginator(
|
|
57
|
+
db,
|
|
58
|
+
'SELECT * FROM tests',
|
|
59
|
+
{},
|
|
60
|
+
{
|
|
61
|
+
total: 30,
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(await paginator.count()).toEqual(10);
|
|
66
|
+
expect(paginator.currentPage()).toEqual(1);
|
|
67
|
+
expect(paginator.perPage()).toEqual(10);
|
|
68
|
+
expect(await paginator.total()).toEqual(30);
|
|
69
|
+
});
|
|
70
|
+
it('should throw exception if total is not a number', async () => {
|
|
71
|
+
try {
|
|
72
|
+
expect(
|
|
73
|
+
new LengthAwarePaginator(
|
|
74
|
+
db,
|
|
75
|
+
'SELECT * FROM tests',
|
|
76
|
+
{},
|
|
77
|
+
{
|
|
78
|
+
perPage: 5,
|
|
79
|
+
currentPage: 1,
|
|
80
|
+
total: 'test',
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
).toThrow();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
expect(err.name).toEqual('LesgoException');
|
|
86
|
+
expect(err.message).toEqual(
|
|
87
|
+
"Invalid type for 'total', expecting 'number'"
|
|
88
|
+
);
|
|
89
|
+
expect(err.code).toEqual(`${FILE}::FIELD_VALIDATION_EXCEPTION`);
|
|
90
|
+
expect(err.statusCode).toEqual(500);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
it('should return the object version of the paginator', async () => {
|
|
94
|
+
const paginator = new LengthAwarePaginator(
|
|
95
|
+
db,
|
|
96
|
+
'SELECT * FROM total_tests',
|
|
97
|
+
{},
|
|
98
|
+
{
|
|
99
|
+
perPage: 5,
|
|
100
|
+
total: 30,
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
expect(await paginator.toObject()).toMatchObject({
|
|
104
|
+
count: 5,
|
|
105
|
+
previous_page: false,
|
|
106
|
+
current_page: 1,
|
|
107
|
+
next_page: 2,
|
|
108
|
+
per_page: 5,
|
|
109
|
+
last_page: 6,
|
|
110
|
+
total: 30,
|
|
111
|
+
items: [
|
|
112
|
+
{ ...mockDataFirstItem },
|
|
113
|
+
{ ...mockData },
|
|
114
|
+
{ ...mockData },
|
|
115
|
+
{ ...mockData },
|
|
116
|
+
{ ...mockDataLastItem },
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('test total() usage', () => {
|
|
123
|
+
it('should get total number of data using supplied paramater', async () => {
|
|
124
|
+
const paginator = new LengthAwarePaginator(
|
|
125
|
+
db,
|
|
126
|
+
'SELECT * FROM total_tests',
|
|
127
|
+
{},
|
|
128
|
+
{
|
|
129
|
+
perPage: 10,
|
|
130
|
+
currentPage: 1,
|
|
131
|
+
total: 30,
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
expect(await paginator.total()).toEqual(30);
|
|
136
|
+
expect(db.select).not.toHaveBeenCalled();
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('test lastPage() usage', () => {
|
|
141
|
+
it('should get the last page using supplied paramater as total data', async () => {
|
|
142
|
+
const paginator1 = new LengthAwarePaginator(
|
|
143
|
+
db,
|
|
144
|
+
'SELECT * FROM total_tests',
|
|
145
|
+
{},
|
|
146
|
+
{
|
|
147
|
+
perPage: 10,
|
|
148
|
+
currentPage: 1,
|
|
149
|
+
total: 30,
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
expect(await paginator1.lastPage()).toEqual(3);
|
|
153
|
+
|
|
154
|
+
const paginator2 = new LengthAwarePaginator(
|
|
155
|
+
db,
|
|
156
|
+
'SELECT * FROM total_tests',
|
|
157
|
+
{},
|
|
158
|
+
{
|
|
159
|
+
perPage: 5,
|
|
160
|
+
currentPage: 1,
|
|
161
|
+
total: 30,
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
expect(await paginator2.lastPage()).toEqual(6);
|
|
165
|
+
|
|
166
|
+
const paginator3 = new LengthAwarePaginator(
|
|
167
|
+
db,
|
|
168
|
+
'SELECT * FROM total_tests',
|
|
169
|
+
{},
|
|
170
|
+
{
|
|
171
|
+
perPage: 7,
|
|
172
|
+
currentPage: 1,
|
|
173
|
+
total: 30,
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
expect(await paginator3.lastPage()).toEqual(5);
|
|
177
|
+
|
|
178
|
+
expect(db.select).not.toHaveBeenCalled();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import Paginator from '../pagination/Paginator';
|
|
2
|
+
import {
|
|
3
|
+
mockData,
|
|
4
|
+
mockDataFirstItem,
|
|
5
|
+
mockDataLastItem,
|
|
6
|
+
} from '../../utils/__mocks__/db';
|
|
7
|
+
import db from '../../utils/db';
|
|
8
|
+
|
|
9
|
+
jest.mock('../../utils/db');
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
db.select.mockClear();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const FILE = 'Services/pagination/Paginator';
|
|
16
|
+
|
|
17
|
+
describe('test Paginator instantiate', () => {
|
|
18
|
+
it.each`
|
|
19
|
+
currentPage | perPage | expectedCount | firstItem | lastItem
|
|
20
|
+
${undefined} | ${undefined} | ${10} | ${mockData} | ${mockData}
|
|
21
|
+
${undefined} | ${5} | ${5} | ${mockDataFirstItem} | ${mockDataLastItem}
|
|
22
|
+
`(
|
|
23
|
+
'should not throw exception if page is $page and perPage is $perPage',
|
|
24
|
+
async ({ currentPage, perPage, expectedCount, firstItem, lastItem }) => {
|
|
25
|
+
const paginator = new Paginator(
|
|
26
|
+
db,
|
|
27
|
+
'SELECT * FROM tests',
|
|
28
|
+
{},
|
|
29
|
+
{
|
|
30
|
+
perPage,
|
|
31
|
+
currentPage,
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(await paginator.count()).toEqual(expectedCount);
|
|
36
|
+
expect(paginator.currentPage()).toEqual(1);
|
|
37
|
+
expect(await paginator.firstItem()).toMatchObject(firstItem);
|
|
38
|
+
expect(await paginator.lastItem()).toMatchObject(lastItem);
|
|
39
|
+
expect(paginator.perPage()).toEqual(expectedCount);
|
|
40
|
+
expect(await paginator.total()).toEqual(10);
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
it('should be instantiated without options', async () => {
|
|
45
|
+
const paginator = new Paginator(db, 'SELECT * FROM tests', {});
|
|
46
|
+
|
|
47
|
+
expect(await paginator.count()).toEqual(10);
|
|
48
|
+
expect(paginator.currentPage()).toEqual(1);
|
|
49
|
+
expect(await paginator.firstItem()).toMatchObject(mockData);
|
|
50
|
+
expect(await paginator.lastItem()).toMatchObject(mockData);
|
|
51
|
+
expect(paginator.perPage()).toEqual(10);
|
|
52
|
+
expect(await paginator.total()).toEqual(10);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it.each`
|
|
56
|
+
currentPage | perPage | errorName | errorMessage | errorCode | errorStatusCode
|
|
57
|
+
${'sample'} | ${10} | ${'LesgoException'} | ${"Invalid type for 'currentPage', expecting 'number'"} | ${`${FILE}::FIELD_VALIDATION_EXCEPTION`} | ${500}
|
|
58
|
+
${1} | ${'sample'} | ${'LesgoException'} | ${"Invalid type for 'perPage', expecting 'number'"} | ${`${FILE}::FIELD_VALIDATION_EXCEPTION`} | ${500}
|
|
59
|
+
`(
|
|
60
|
+
'should throw $errorMessage when page is $page and perPage is $perPage',
|
|
61
|
+
({
|
|
62
|
+
currentPage,
|
|
63
|
+
perPage,
|
|
64
|
+
errorName,
|
|
65
|
+
errorMessage,
|
|
66
|
+
errorCode,
|
|
67
|
+
errorStatusCode,
|
|
68
|
+
}) => {
|
|
69
|
+
try {
|
|
70
|
+
const values = new Paginator(
|
|
71
|
+
db,
|
|
72
|
+
'SELECT * FROM tests',
|
|
73
|
+
{},
|
|
74
|
+
{
|
|
75
|
+
perPage,
|
|
76
|
+
currentPage,
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
expect(values).toThrow();
|
|
80
|
+
} catch (err) {
|
|
81
|
+
expect(err.name).toEqual(errorName);
|
|
82
|
+
expect(err.message).toEqual(errorMessage);
|
|
83
|
+
expect(err.code).toEqual(errorCode);
|
|
84
|
+
expect(err.statusCode).toEqual(errorStatusCode);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
it('should return the first item of the result', async () => {
|
|
90
|
+
const paginator = new Paginator(
|
|
91
|
+
db,
|
|
92
|
+
'SELECT * FROM tests',
|
|
93
|
+
{},
|
|
94
|
+
{
|
|
95
|
+
perPage: 5,
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
expect(await paginator.firstItem()).toMatchObject(mockDataFirstItem);
|
|
100
|
+
});
|
|
101
|
+
it('should return the last item of the result', async () => {
|
|
102
|
+
const paginator = new Paginator(
|
|
103
|
+
db,
|
|
104
|
+
'SELECT * FROM tests',
|
|
105
|
+
{},
|
|
106
|
+
{
|
|
107
|
+
perPage: 5,
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(await paginator.lastItem()).toMatchObject(mockDataLastItem);
|
|
112
|
+
});
|
|
113
|
+
it('should return the defined per page', () => {
|
|
114
|
+
const paginator = new Paginator(
|
|
115
|
+
db,
|
|
116
|
+
'SELECT * FROM tests',
|
|
117
|
+
{},
|
|
118
|
+
{
|
|
119
|
+
perPage: 5,
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
expect(paginator.perPage()).toEqual(5);
|
|
124
|
+
});
|
|
125
|
+
it('should return the previous page if exist', () => {
|
|
126
|
+
const paginator1 = new Paginator(
|
|
127
|
+
db,
|
|
128
|
+
'SELECT * FROM tests',
|
|
129
|
+
{},
|
|
130
|
+
{
|
|
131
|
+
perPage: 5,
|
|
132
|
+
currentPage: 2,
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
expect(paginator1.previousPage()).toEqual(1);
|
|
136
|
+
|
|
137
|
+
const paginator2 = new Paginator(
|
|
138
|
+
db,
|
|
139
|
+
'SELECT * FROM tests',
|
|
140
|
+
{},
|
|
141
|
+
{
|
|
142
|
+
perPage: 5,
|
|
143
|
+
currentPage: 1,
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
expect(paginator2.previousPage()).toEqual(false);
|
|
147
|
+
});
|
|
148
|
+
it('should return the next page if exist', async () => {
|
|
149
|
+
const paginator1 = new Paginator(
|
|
150
|
+
db,
|
|
151
|
+
'SELECT * FROM tests',
|
|
152
|
+
{},
|
|
153
|
+
{
|
|
154
|
+
perPage: 5,
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
expect(await paginator1.nextPage()).toEqual(2);
|
|
158
|
+
|
|
159
|
+
const paginator2 = new Paginator(
|
|
160
|
+
db,
|
|
161
|
+
'SELECT * FROM tests',
|
|
162
|
+
{},
|
|
163
|
+
{
|
|
164
|
+
perPage: 5,
|
|
165
|
+
currentPage: 2,
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
expect(await paginator2.nextPage()).toEqual(3);
|
|
169
|
+
|
|
170
|
+
const paginator3 = new Paginator(
|
|
171
|
+
db,
|
|
172
|
+
'SELECT * FROM tests',
|
|
173
|
+
{},
|
|
174
|
+
{
|
|
175
|
+
perPage: 5,
|
|
176
|
+
currentPage: 3,
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
expect(await paginator3.nextPage()).toEqual(false);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('test count() usage', () => {
|
|
184
|
+
it('should count number of items of the current page', async () => {
|
|
185
|
+
const paginator = new Paginator(
|
|
186
|
+
db,
|
|
187
|
+
'SELECT * FROM tests',
|
|
188
|
+
{},
|
|
189
|
+
{
|
|
190
|
+
perPage: 5,
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
expect(await paginator.count()).toEqual(5);
|
|
195
|
+
});
|
|
196
|
+
it('should only run executeQuery once', async () => {
|
|
197
|
+
const paginator = new Paginator(
|
|
198
|
+
db,
|
|
199
|
+
'SELECT * FROM tests',
|
|
200
|
+
{},
|
|
201
|
+
{
|
|
202
|
+
perPage: 5,
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
await paginator.count();
|
|
207
|
+
await paginator.count();
|
|
208
|
+
await paginator.count();
|
|
209
|
+
await paginator.count();
|
|
210
|
+
await paginator.count();
|
|
211
|
+
|
|
212
|
+
expect(db.select).toHaveBeenCalledTimes(1);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe('test currentPage() usage', () => {
|
|
217
|
+
it('should return 1 as current page if no currentPage is defined', () => {
|
|
218
|
+
const paginator = new Paginator(
|
|
219
|
+
db,
|
|
220
|
+
'SELECT * FROM tests',
|
|
221
|
+
{},
|
|
222
|
+
{
|
|
223
|
+
perPage: 5,
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
expect(paginator.currentPage()).toEqual(1);
|
|
228
|
+
});
|
|
229
|
+
it('should return the defined current page on instantiation', () => {
|
|
230
|
+
const paginator = new Paginator(
|
|
231
|
+
db,
|
|
232
|
+
'SELECT * FROM tests',
|
|
233
|
+
{},
|
|
234
|
+
{
|
|
235
|
+
perPage: 5,
|
|
236
|
+
currentPage: 2,
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
expect(paginator.currentPage()).toEqual(2);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
describe('test items() usage', () => {
|
|
245
|
+
it('should return all results from the current page', async () => {
|
|
246
|
+
const paginator = new Paginator(
|
|
247
|
+
db,
|
|
248
|
+
'SELECT * FROM tests',
|
|
249
|
+
{},
|
|
250
|
+
{
|
|
251
|
+
perPage: 5,
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
expect(await paginator.items()).toMatchObject([
|
|
256
|
+
{ ...mockDataFirstItem },
|
|
257
|
+
{ ...mockData },
|
|
258
|
+
{ ...mockData },
|
|
259
|
+
{ ...mockData },
|
|
260
|
+
{ ...mockDataLastItem },
|
|
261
|
+
]);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should only run executeQuery once', async () => {
|
|
265
|
+
const paginator = new Paginator(
|
|
266
|
+
db,
|
|
267
|
+
'SELECT * FROM tests',
|
|
268
|
+
{},
|
|
269
|
+
{
|
|
270
|
+
perPage: 5,
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
await paginator.items();
|
|
275
|
+
await paginator.items();
|
|
276
|
+
await paginator.items();
|
|
277
|
+
await paginator.items();
|
|
278
|
+
|
|
279
|
+
expect(db.select).toHaveBeenCalledTimes(1);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('test toObject() usage', () => {
|
|
284
|
+
it('should return object version of the paginator', async () => {
|
|
285
|
+
const paginator = new Paginator(
|
|
286
|
+
db,
|
|
287
|
+
'SELECT * FROM tests',
|
|
288
|
+
{},
|
|
289
|
+
{
|
|
290
|
+
perPage: 5,
|
|
291
|
+
}
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
expect(await paginator.toObject()).toMatchObject({
|
|
295
|
+
count: 5,
|
|
296
|
+
previous_page: false,
|
|
297
|
+
current_page: 1,
|
|
298
|
+
next_page: 2,
|
|
299
|
+
last_page: 2,
|
|
300
|
+
per_page: 5,
|
|
301
|
+
total: 10,
|
|
302
|
+
items: [
|
|
303
|
+
{ ...mockDataFirstItem },
|
|
304
|
+
{ ...mockData },
|
|
305
|
+
{ ...mockData },
|
|
306
|
+
{ ...mockData },
|
|
307
|
+
{ ...mockDataLastItem },
|
|
308
|
+
],
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('should only run executeQuery twice', async () => {
|
|
313
|
+
const paginator = new Paginator(
|
|
314
|
+
db,
|
|
315
|
+
'SELECT * FROM tests',
|
|
316
|
+
{},
|
|
317
|
+
{
|
|
318
|
+
perPage: 5,
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
await paginator.toObject();
|
|
323
|
+
await paginator.toObject();
|
|
324
|
+
await paginator.toObject();
|
|
325
|
+
await paginator.toObject();
|
|
326
|
+
|
|
327
|
+
expect(db.select).toHaveBeenCalledTimes(2);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
describe('test total() usage', () => {
|
|
332
|
+
it('should get total number of data using default countTotalItems method', async () => {
|
|
333
|
+
const paginator = new Paginator(
|
|
334
|
+
db,
|
|
335
|
+
'SELECT * FROM total_tests',
|
|
336
|
+
{},
|
|
337
|
+
{
|
|
338
|
+
currentPage: 1,
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
expect(await paginator.total()).toEqual(30);
|
|
343
|
+
expect(db.select).toHaveBeenCalled();
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
describe('test lastPage() usage', () => {
|
|
348
|
+
it('should get the last page using default countTotalItems method when getting total data', async () => {
|
|
349
|
+
const paginator1 = new Paginator(
|
|
350
|
+
db,
|
|
351
|
+
'SELECT * FROM total_tests',
|
|
352
|
+
{},
|
|
353
|
+
{
|
|
354
|
+
currentPage: 1,
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
expect(await paginator1.lastPage()).toEqual(3);
|
|
358
|
+
|
|
359
|
+
const paginator2 = new Paginator(
|
|
360
|
+
db,
|
|
361
|
+
'SELECT * FROM total_tests',
|
|
362
|
+
{},
|
|
363
|
+
{
|
|
364
|
+
perPage: 5,
|
|
365
|
+
currentPage: 1,
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
expect(await paginator2.lastPage()).toEqual(6);
|
|
369
|
+
|
|
370
|
+
const paginator3 = new Paginator(
|
|
371
|
+
db,
|
|
372
|
+
'SELECT * FROM total_tests',
|
|
373
|
+
{},
|
|
374
|
+
{
|
|
375
|
+
perPage: 7,
|
|
376
|
+
currentPage: 1,
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
expect(await paginator3.lastPage()).toEqual(5);
|
|
380
|
+
|
|
381
|
+
expect(db.select).toHaveBeenCalled();
|
|
382
|
+
});
|
|
383
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import Paginator from './Paginator';
|
|
2
|
+
import LesgoException from '../../exceptions/LesgoException';
|
|
3
|
+
import validateFields from '../../utils/validateFields';
|
|
4
|
+
|
|
5
|
+
const FILE = 'Services/pagination/LengthAwarePaginator';
|
|
6
|
+
|
|
7
|
+
export default class LengthAwarePaginator extends Paginator {
|
|
8
|
+
/**
|
|
9
|
+
* Constructor
|
|
10
|
+
*
|
|
11
|
+
* @param db
|
|
12
|
+
* @param sql
|
|
13
|
+
* @param sqlParams
|
|
14
|
+
* @param options
|
|
15
|
+
* @param connection
|
|
16
|
+
*/
|
|
17
|
+
constructor(db, sql, sqlParams, options, connection = {}) {
|
|
18
|
+
const validFields = [{ key: 'total', type: 'number', required: true }];
|
|
19
|
+
|
|
20
|
+
let validated = {};
|
|
21
|
+
try {
|
|
22
|
+
validated = validateFields(options, validFields);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw new LesgoException(
|
|
25
|
+
error.message,
|
|
26
|
+
`${FILE}::FIELD_VALIDATION_EXCEPTION`,
|
|
27
|
+
500,
|
|
28
|
+
{
|
|
29
|
+
...options,
|
|
30
|
+
error,
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const { total } = validated;
|
|
36
|
+
|
|
37
|
+
super(db, sql, sqlParams, options, connection);
|
|
38
|
+
this.totalProp = total;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Total items in all pages.
|
|
43
|
+
*
|
|
44
|
+
* @returns {null|number}
|
|
45
|
+
*/
|
|
46
|
+
async total() {
|
|
47
|
+
return this.totalProp;
|
|
48
|
+
}
|
|
49
|
+
}
|