@snowtop/ent 0.1.0-alpha90 → 0.1.0-alpha91
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/action/orchestrator.js +5 -1
- package/core/clause.d.ts +15 -0
- package/core/clause.js +44 -2
- package/core/config.js +5 -1
- package/core/db.js +5 -1
- package/core/ent.js +7 -8
- package/core/loaders/assoc_count_loader.d.ts +1 -0
- package/core/loaders/assoc_count_loader.js +8 -1
- package/core/loaders/assoc_edge_loader.js +5 -1
- package/core/loaders/object_loader.js +5 -1
- package/core/loaders/query_loader.js +5 -1
- package/core/loaders/raw_count_loader.js +5 -1
- package/core/privacy.d.ts +6 -6
- package/core/query/assoc_query.d.ts +1 -0
- package/core/query/assoc_query.js +9 -1
- package/core/query/custom_clause_query.d.ts +2 -0
- package/core/query/custom_clause_query.js +9 -3
- package/core/query/custom_query.d.ts +2 -2
- package/core/query/custom_query.js +29 -21
- package/core/query/query.d.ts +7 -3
- package/core/query/query.js +101 -60
- package/core/query/shared_assoc_test.d.ts +2 -1
- package/core/query/shared_assoc_test.js +24 -45
- package/core/query/shared_test.d.ts +5 -1
- package/core/query/shared_test.js +354 -301
- package/graphql/graphql.js +10 -6
- package/graphql/query/shared_edge_connection.js +1 -15
- package/imports/index.js +5 -1
- package/index.js +5 -1
- package/package.json +1 -1
- package/schema/field.js +11 -1
- package/schema/index.js +5 -1
- package/schema/schema.d.ts +1 -0
- package/scripts/custom_compiler.js +10 -6
- package/scripts/custom_graphql.js +5 -1
- package/scripts/read_schema.js +5 -1
- package/testutils/db/temp_db.d.ts +6 -5
- package/testutils/db/temp_db.js +40 -28
- package/testutils/db_mock.js +3 -1
- package/testutils/ent-graphql-tests/index.js +8 -1
- package/testutils/fake_data/const.d.ts +2 -1
- package/testutils/fake_data/const.js +3 -0
- package/testutils/fake_data/fake_contact.d.ts +2 -0
- package/testutils/fake_data/fake_tag.d.ts +35 -0
- package/testutils/fake_data/fake_tag.js +88 -0
- package/testutils/fake_data/fake_user.d.ts +2 -0
- package/testutils/fake_data/index.js +5 -1
- package/testutils/fake_data/internal.d.ts +2 -0
- package/testutils/fake_data/internal.js +7 -1
- package/testutils/fake_data/tag_query.d.ts +13 -0
- package/testutils/fake_data/tag_query.js +43 -0
- package/testutils/fake_data/test_helpers.d.ts +8 -2
- package/testutils/fake_data/test_helpers.js +21 -7
- package/testutils/fake_data/user_query.d.ts +5 -0
- package/testutils/fake_data/user_query.js +28 -3
- package/testutils/test_edge_global_schema.js +5 -1
- package/testutils/write.js +5 -1
- package/tsc/ast.js +5 -1
- package/tsc/compilerOptions.js +5 -1
- package/tsc/move_generated.js +5 -1
- package/tsc/transform.js +5 -1
- package/tsc/transform_action.js +5 -1
- package/tsc/transform_schema.js +5 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.commonTests = void 0;
|
|
4
|
-
const db_mock_1 = require("../../testutils/db_mock");
|
|
5
4
|
const ent_1 = require("../ent");
|
|
6
5
|
const viewer_1 = require("../viewer");
|
|
7
6
|
const index_1 = require("../../testutils/fake_data/index");
|
|
@@ -12,236 +11,284 @@ const logger_1 = require("../logger");
|
|
|
12
11
|
const test_edge_global_schema_1 = require("../../testutils/test_edge_global_schema");
|
|
13
12
|
const builder_1 = require("../../testutils/builder");
|
|
14
13
|
const action_1 = require("../../action");
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.ents = ents;
|
|
21
|
-
this.defaultViewer = defaultViewer;
|
|
22
|
-
this.allContacts = [];
|
|
23
|
-
this.filteredContacts = [];
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
const q = this.newQuery(this.defaultViewer);
|
|
26
|
-
// TODO sad not generic enough
|
|
27
|
-
this.customQuery =
|
|
28
|
-
q instanceof index_1.UserToContactsFkeyQuery ||
|
|
29
|
-
q instanceof index_1.UserToContactsFkeyQueryDeprecated;
|
|
30
|
-
}
|
|
31
|
-
async createData() {
|
|
32
|
-
[this.user, this.allContacts] = await (0, test_helpers_1.createAllContacts)();
|
|
33
|
-
// this.allContacts = this.allContacts.reverse();
|
|
34
|
-
this.filteredContacts = this.ents(this.allContacts);
|
|
35
|
-
db_mock_1.QueryRecorder.clearQueries();
|
|
36
|
-
}
|
|
37
|
-
getQuery(viewer) {
|
|
38
|
-
return this.filter(this.newQuery(viewer || this.defaultViewer, this.user), this.user, this.allContacts);
|
|
39
|
-
}
|
|
40
|
-
async testIDs() {
|
|
41
|
-
const ids = await this.getQuery().queryIDs();
|
|
42
|
-
this.verifyIDs(ids);
|
|
43
|
-
}
|
|
44
|
-
verifyIDs(ids) {
|
|
45
|
-
expect(ids).toEqual(this.filteredContacts.map((contact) => contact.id));
|
|
46
|
-
}
|
|
47
|
-
// rawCount isn't affected by filters...
|
|
48
|
-
async testRawCount(expectedCount) {
|
|
49
|
-
const count = await this.getQuery().queryRawCount();
|
|
50
|
-
this.verifyRawCount(count, expectedCount);
|
|
51
|
-
}
|
|
52
|
-
verifyRawCount(count, expectedCount) {
|
|
53
|
-
expect(count).toBe(expectedCount ?? test_helpers_1.inputs.length);
|
|
54
|
-
}
|
|
55
|
-
async testCount(expectedCount) {
|
|
56
|
-
const count = await this.getQuery().queryCount();
|
|
57
|
-
this.verifyCount(count, expectedCount);
|
|
58
|
-
}
|
|
59
|
-
verifyCount(count, expectedCount) {
|
|
60
|
-
expect(count).toBe(expectedCount ?? this.filteredContacts.length);
|
|
61
|
-
}
|
|
62
|
-
async testEdges() {
|
|
63
|
-
const edges = await this.getQuery().queryEdges();
|
|
64
|
-
this.verifyEdges(edges);
|
|
14
|
+
const clause_1 = require("../clause");
|
|
15
|
+
function getWhereClause(query) {
|
|
16
|
+
const idx = query.query.indexOf("WHERE");
|
|
17
|
+
if (idx !== -1) {
|
|
18
|
+
return query.query.substr(idx + 6);
|
|
65
19
|
}
|
|
66
|
-
|
|
67
|
-
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const commonTests = (opts) => {
|
|
23
|
+
(0, logger_1.setLogLevels)(["query", "error"]);
|
|
24
|
+
const ml = opts.ml;
|
|
25
|
+
ml.mock();
|
|
26
|
+
function isCustomQuery(q) {
|
|
27
|
+
if (q.customQuery !== undefined) {
|
|
28
|
+
return q.customQuery;
|
|
29
|
+
}
|
|
68
30
|
// TODO sad not generic enough
|
|
69
|
-
|
|
70
|
-
|
|
31
|
+
return (q instanceof index_1.UserToContactsFkeyQuery ||
|
|
32
|
+
q instanceof index_1.UserToContactsFkeyQueryDeprecated ||
|
|
33
|
+
q instanceof index_1.UserToContactsFkeyQueryAsc);
|
|
34
|
+
}
|
|
35
|
+
class TestQueryFilter {
|
|
36
|
+
constructor(filter, newQuery, ents, defaultViewer) {
|
|
37
|
+
this.filter = filter;
|
|
38
|
+
this.newQuery = newQuery;
|
|
39
|
+
this.ents = ents;
|
|
40
|
+
this.defaultViewer = defaultViewer;
|
|
41
|
+
this.allContacts = [];
|
|
42
|
+
this.filteredContacts = [];
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
const q = this.newQuery(this.defaultViewer);
|
|
45
|
+
this.customQuery = isCustomQuery(q);
|
|
71
46
|
}
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
async createData() {
|
|
48
|
+
[this.user, this.allContacts] = await (0, test_helpers_1.createAllContacts)();
|
|
49
|
+
// this.allContacts = this.allContacts.reverse();
|
|
50
|
+
this.filteredContacts = this.ents(this.allContacts);
|
|
51
|
+
ml.clear();
|
|
74
52
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const ents = await this.getQuery(v || new viewer_1.IDViewer(this.user.id)).queryEnts();
|
|
78
|
-
this.verifyEnts(ents);
|
|
79
|
-
return ents;
|
|
80
|
-
}
|
|
81
|
-
async testEntsCache() {
|
|
82
|
-
if (!this.customQuery) {
|
|
83
|
-
return;
|
|
53
|
+
getQuery(viewer) {
|
|
54
|
+
return this.filter(this.newQuery(viewer || this.defaultViewer, this.user), this.user, this.allContacts);
|
|
84
55
|
}
|
|
85
|
-
(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const v = new test_context_1.TestContext(new viewer_1.IDViewer(this.user.id)).getViewer();
|
|
89
|
-
const ents = await this.testEnts(v);
|
|
90
|
-
expect(ml.logs.length).toBe(1);
|
|
91
|
-
expect(ml.logs[0].query).toMatch(/SELECT (.+) FROM /);
|
|
92
|
-
await Promise.all(ents.map((ent) => index_1.FakeContact.loadX(v, ent.id)));
|
|
93
|
-
expect(ml.logs.length).toBe(this.filteredContacts.length + 1);
|
|
94
|
-
for (const log of ml.logs.slice(1)) {
|
|
95
|
-
expect(log["ent-cache-hit"]).toBeDefined();
|
|
56
|
+
async testIDs() {
|
|
57
|
+
const ids = await this.getQuery().queryIDs();
|
|
58
|
+
this.verifyIDs(ids);
|
|
96
59
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
async testDataCache() {
|
|
101
|
-
if (!this.customQuery) {
|
|
102
|
-
return;
|
|
60
|
+
verifyIDs(ids) {
|
|
61
|
+
expect(ids).toEqual(this.filteredContacts.map((contact) => contact.id));
|
|
103
62
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const ents = await this.testEnts(v);
|
|
109
|
-
expect(ml.logs.length).toBe(1);
|
|
110
|
-
expect(ml.logs[0].query).toMatch(/SELECT (.+) FROM /);
|
|
111
|
-
await Promise.all(ents.map((ent) => index_1.FakeContact.loadRawData(ent.id, v.context)));
|
|
112
|
-
expect(ml.logs.length).toBe(this.filteredContacts.length + 1);
|
|
113
|
-
for (const log of ml.logs.slice(1)) {
|
|
114
|
-
expect(log["dataloader-cache-hit"]).toBeDefined();
|
|
63
|
+
// rawCount isn't affected by filters...
|
|
64
|
+
async testRawCount(expectedCount) {
|
|
65
|
+
const count = await this.getQuery().queryRawCount();
|
|
66
|
+
this.verifyRawCount(count, expectedCount);
|
|
115
67
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
68
|
+
verifyRawCount(count, expectedCount) {
|
|
69
|
+
expect(count).toBe(expectedCount ?? test_helpers_1.inputs.length);
|
|
70
|
+
}
|
|
71
|
+
async testCount(expectedCount) {
|
|
72
|
+
const count = await this.getQuery().queryCount();
|
|
73
|
+
this.verifyCount(count, expectedCount);
|
|
74
|
+
}
|
|
75
|
+
verifyCount(count, expectedCount) {
|
|
76
|
+
expect(count).toBe(expectedCount ?? this.filteredContacts.length);
|
|
77
|
+
}
|
|
78
|
+
async testEdges() {
|
|
79
|
+
const edges = await this.getQuery().queryEdges();
|
|
80
|
+
this.verifyEdges(edges);
|
|
81
|
+
}
|
|
82
|
+
verifyEdges(edges) {
|
|
83
|
+
const q = this.getQuery();
|
|
84
|
+
// TODO sad not generic enough
|
|
85
|
+
if (this.customQuery) {
|
|
86
|
+
(0, test_helpers_1.verifyUserToContactRawData)(this.user, edges, this.filteredContacts);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
(0, test_helpers_1.verifyUserToContactEdges)(this.user, edges, this.filteredContacts);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async testEnts(v) {
|
|
93
|
+
const ents = await this.getQuery(v || new viewer_1.IDViewer(this.user.id)).queryEnts();
|
|
94
|
+
this.verifyEnts(ents);
|
|
95
|
+
return ents;
|
|
96
|
+
}
|
|
97
|
+
async testEntsCache() {
|
|
98
|
+
if (!this.customQuery) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
(0, logger_1.setLogLevels)(["query", "cache"]);
|
|
102
|
+
const v = new test_context_1.TestContext(new viewer_1.IDViewer(this.user.id)).getViewer();
|
|
103
|
+
const ents = await this.testEnts(v);
|
|
104
|
+
expect(ml.logs.length).toBe(1);
|
|
105
|
+
expect(ml.logs[0].query).toMatch(/SELECT (.+) FROM /);
|
|
106
|
+
await Promise.all(ents.map((ent) => index_1.FakeContact.loadX(v, ent.id)));
|
|
107
|
+
expect(ml.logs.length).toBe(this.filteredContacts.length + 1);
|
|
108
|
+
for (const log of ml.logs.slice(1)) {
|
|
109
|
+
expect(log["ent-cache-hit"]).toBeDefined();
|
|
110
|
+
}
|
|
111
|
+
// "restore" back to previous
|
|
112
|
+
(0, logger_1.setLogLevels)("query");
|
|
113
|
+
}
|
|
114
|
+
async testDataCache() {
|
|
115
|
+
if (!this.customQuery) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
(0, logger_1.setLogLevels)(["query", "cache"]);
|
|
119
|
+
const v = new test_context_1.TestContext(new viewer_1.IDViewer(this.user.id)).getViewer();
|
|
120
|
+
const ents = await this.testEnts(v);
|
|
121
|
+
expect(ml.logs.length).toBe(1);
|
|
122
|
+
expect(ml.logs[0].query).toMatch(/SELECT (.+) FROM /);
|
|
123
|
+
await Promise.all(ents.map((ent) => index_1.FakeContact.loadRawData(ent.id, v.context)));
|
|
124
|
+
expect(ml.logs.length).toBe(this.filteredContacts.length + 1);
|
|
125
|
+
for (const log of ml.logs.slice(1)) {
|
|
126
|
+
expect(log["dataloader-cache-hit"]).toBeDefined();
|
|
127
|
+
}
|
|
128
|
+
// "restore" back to previous
|
|
129
|
+
(0, logger_1.setLogLevels)("query");
|
|
130
|
+
}
|
|
131
|
+
verifyEnts(ents) {
|
|
132
|
+
(0, test_helpers_1.verifyUserToContacts)(this.user, ents, this.filteredContacts);
|
|
133
|
+
}
|
|
134
|
+
async testAll(expectedCount) {
|
|
135
|
+
const query = this.getQuery(new viewer_1.IDViewer(this.user.id));
|
|
136
|
+
const [edges, count, ids, rawCount, ents] = await Promise.all([
|
|
137
|
+
query.queryEdges(),
|
|
138
|
+
query.queryCount(),
|
|
139
|
+
query.queryIDs(),
|
|
140
|
+
query.queryRawCount(),
|
|
141
|
+
query.queryEnts(),
|
|
142
|
+
]);
|
|
143
|
+
this.verifyCount(count, expectedCount);
|
|
144
|
+
this.verifyEdges(edges);
|
|
145
|
+
this.verifyIDs(ids);
|
|
146
|
+
this.verifyRawCount(rawCount, expectedCount);
|
|
147
|
+
this.verifyEnts(ents);
|
|
143
148
|
}
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
}
|
|
150
|
+
function verifyQuery(filter, { length = 1, numQueries = 1, limit = ent_1.DefaultLimit, disablePaginationBump = false, orderby = opts.orderby, }) {
|
|
151
|
+
const uniqCol = isCustomQuery(filter) ? "id" : "id2";
|
|
152
|
+
expect(ml.logs.length).toBe(length);
|
|
146
153
|
for (let i = 0; i < numQueries; i++) {
|
|
147
|
-
const
|
|
154
|
+
const whereClause = getWhereClause(ml.logs[i]);
|
|
148
155
|
let expLimit = disablePaginationBump ? limit : limit + 1;
|
|
149
|
-
expect(
|
|
156
|
+
expect(whereClause, `${i}`).toBe(
|
|
150
157
|
// default limit
|
|
151
|
-
`${opts.
|
|
158
|
+
`${opts.clause.clause(1)} ORDER BY ${opts.sortCol} ${orderby}, ${uniqCol} ${orderby} LIMIT ${expLimit}`);
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
function verifyCountQuery({ length = 1, numQueries = 1 }) {
|
|
155
|
-
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const queries = db_mock_1.QueryRecorder.getCurrentQueries();
|
|
159
|
-
expect(queries.length).toBe(length);
|
|
162
|
+
expect(ml.logs.length).toBe(length);
|
|
160
163
|
for (let i = 0; i < numQueries; i++) {
|
|
161
|
-
const
|
|
162
|
-
expect(
|
|
163
|
-
expect(query.qs?.columns).toHaveLength(1);
|
|
164
|
-
expect(query.qs?.columns).toStrictEqual(["count(1) as count"]);
|
|
164
|
+
const whereClause = getWhereClause(ml.logs[i]);
|
|
165
|
+
expect(whereClause).toBe(opts.clause.clause(1));
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
|
-
function verifyFirstAfterCursorQuery(length = 1) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const query = queries[0];
|
|
174
|
-
const result = [...opts.where.matchAll(preparedVar)];
|
|
175
|
-
let parts = opts.where.split(" AND ");
|
|
168
|
+
function verifyFirstAfterCursorQuery(filter, length = 1, limit = 3) {
|
|
169
|
+
// cache showing up in a few because of cross runs...
|
|
170
|
+
expect(ml.logs.length).toBeGreaterThanOrEqual(length);
|
|
171
|
+
const uniqCol = isCustomQuery(filter) ? "id" : "id2";
|
|
172
|
+
let parts = opts.clause.clause(1).split(" AND ");
|
|
173
|
+
const cmp = (0, clause_1.PaginationMultipleColsSubQuery)(opts.sortCol, opts.orderby === "DESC" ? "<" : ">", opts.tableName, uniqCol, "").clause(opts.clause.values().length + 1);
|
|
176
174
|
if (parts[parts.length - 1] === "deleted_at IS NULL") {
|
|
177
175
|
parts = parts
|
|
178
176
|
.slice(0, parts.length - 1)
|
|
179
|
-
.concat([
|
|
180
|
-
`${opts.sortCol} < $${result.length + 1}`,
|
|
181
|
-
"deleted_at IS NULL",
|
|
182
|
-
]);
|
|
177
|
+
.concat([cmp, "deleted_at IS NULL"]);
|
|
183
178
|
}
|
|
184
179
|
else {
|
|
185
|
-
parts.push(
|
|
180
|
+
parts.push(cmp);
|
|
186
181
|
}
|
|
187
|
-
expect(
|
|
182
|
+
expect(getWhereClause(ml.logs[0])).toBe(`${parts.join(" AND ")} ORDER BY ${opts.sortCol} ${opts.orderby}, ${uniqCol} ${opts.orderby} LIMIT ${limit + 1}`);
|
|
188
183
|
}
|
|
189
|
-
function verifyLastBeforeCursorQuery(length = 1) {
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
function verifyLastBeforeCursorQuery(filter, length = 1, limit = 3) {
|
|
185
|
+
// cache showing up in a few because of cross runs...
|
|
186
|
+
expect(ml.logs.length).toBeGreaterThanOrEqual(length);
|
|
187
|
+
const uniqCol = isCustomQuery(filter) ? "id" : "id2";
|
|
188
|
+
let op = "";
|
|
189
|
+
let orderby = "";
|
|
190
|
+
if (opts.orderby === "DESC") {
|
|
191
|
+
op = ">";
|
|
192
|
+
orderby = "ASC";
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
op = "<";
|
|
196
|
+
orderby = "DESC";
|
|
192
197
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const query = queries[0];
|
|
196
|
-
const result = [...opts.where.matchAll(preparedVar)];
|
|
197
|
-
let parts = opts.where.split(" AND ");
|
|
198
|
+
let parts = opts.clause.clause(1).split(" AND ");
|
|
199
|
+
const cmp = (0, clause_1.PaginationMultipleColsSubQuery)(opts.sortCol, op, opts.tableName, uniqCol, "").clause(opts.clause.values().length + 1);
|
|
198
200
|
if (parts[parts.length - 1] === "deleted_at IS NULL") {
|
|
199
201
|
parts = parts
|
|
200
202
|
.slice(0, parts.length - 1)
|
|
201
|
-
.concat([
|
|
202
|
-
`${opts.sortCol} > $${result.length + 1}`,
|
|
203
|
-
"deleted_at IS NULL",
|
|
204
|
-
]);
|
|
203
|
+
.concat([cmp, "deleted_at IS NULL"]);
|
|
205
204
|
}
|
|
206
205
|
else {
|
|
207
|
-
parts.push(
|
|
206
|
+
parts.push(cmp);
|
|
208
207
|
}
|
|
209
|
-
expect(
|
|
208
|
+
expect(getWhereClause(ml.logs[0])).toBe(
|
|
210
209
|
// extra fetched for pagination
|
|
211
|
-
`${parts.join(" AND ")} ORDER BY ${opts.sortCol}
|
|
210
|
+
`${parts.join(" AND ")} ORDER BY ${opts.sortCol} ${orderby}, ${uniqCol} ${orderby} LIMIT ${limit + 1}`);
|
|
212
211
|
}
|
|
213
212
|
function getViewer() {
|
|
214
|
-
// live db, let's do context because we're testing complicated paths
|
|
215
|
-
// may be worth breaking this out later
|
|
216
|
-
// opts.liveDB no context too...
|
|
217
|
-
// maybe this one we just always hit the db
|
|
218
|
-
// we don't get value out of testing parse_sql no context....
|
|
219
|
-
if (opts.livePostgresDB || opts.sqlite) {
|
|
220
|
-
return new test_context_1.TestContext().getViewer();
|
|
221
|
-
}
|
|
222
|
-
// no context when not live db
|
|
223
213
|
return new viewer_1.LoggedOutViewer();
|
|
224
214
|
}
|
|
225
215
|
function getCursorFrom(contacts, idx) {
|
|
226
|
-
// we depend on the fact that the same time is used for the edge and created_at
|
|
227
|
-
// based on getContactBuilder
|
|
228
|
-
// so regardless of if we're doing assoc or custom queries, we can get the time
|
|
229
|
-
// from the created_at field
|
|
230
216
|
return (0, ent_1.getCursor)({
|
|
231
217
|
row: contacts[idx],
|
|
232
|
-
col: "
|
|
233
|
-
conv: (t) => {
|
|
234
|
-
//sqlite
|
|
235
|
-
if (typeof t === "string") {
|
|
236
|
-
return Date.parse(t);
|
|
237
|
-
}
|
|
238
|
-
return t.getTime();
|
|
239
|
-
},
|
|
240
|
-
// we want the right column to be encoded in the cursor as opposed e.g. time for
|
|
241
|
-
// assoc queries, created_at for index/custom queries
|
|
242
|
-
cursorKey: opts.sortCol,
|
|
218
|
+
col: "id",
|
|
243
219
|
});
|
|
244
220
|
}
|
|
221
|
+
function getVerifyAfterEachCursor(edges, pageLength, user) {
|
|
222
|
+
let query;
|
|
223
|
+
async function verify(i, hasEdge, hasNextPage, cursor) {
|
|
224
|
+
ml.clear();
|
|
225
|
+
query = opts.newQuery(getViewer(), user);
|
|
226
|
+
const newEdges = await query.first(pageLength, cursor).queryEdges();
|
|
227
|
+
const pagination = query.paginationInfo().get(user.id);
|
|
228
|
+
if (hasEdge) {
|
|
229
|
+
expect(newEdges[0], `${i}`).toStrictEqual(edges[i]);
|
|
230
|
+
expect(newEdges.length, `${i}`).toBe(edges.length - i >= pageLength ? pageLength : edges.length - i);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
expect(newEdges.length, `${i}`).toBe(0);
|
|
234
|
+
}
|
|
235
|
+
if (hasNextPage) {
|
|
236
|
+
expect(pagination?.hasNextPage, `${i}`).toBe(true);
|
|
237
|
+
expect(pagination?.hasPreviousPage, `${i}`).toBe(false);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
expect(pagination?.hasNextPage, `${i}`).toBe(undefined);
|
|
241
|
+
expect(pagination?.hasNextPage, `${i}`).toBe(undefined);
|
|
242
|
+
}
|
|
243
|
+
if (cursor) {
|
|
244
|
+
verifyFirstAfterCursorQuery(query, 1, pageLength);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
verifyQuery(query, { orderby: opts.orderby, limit: pageLength });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function getCursor(edge) {
|
|
251
|
+
return query.getCursor(edge);
|
|
252
|
+
}
|
|
253
|
+
return { verify, getCursor };
|
|
254
|
+
}
|
|
255
|
+
function getVerifyBeforeEachCursor(edges, pageLength, user) {
|
|
256
|
+
let query;
|
|
257
|
+
async function verify(i, hasEdge, hasPreviousPage, cursor) {
|
|
258
|
+
ml.clear();
|
|
259
|
+
query = opts.newQuery(getViewer(), user);
|
|
260
|
+
const newEdges = await query.last(pageLength, cursor).queryEdges();
|
|
261
|
+
const pagination = query.paginationInfo().get(user.id);
|
|
262
|
+
if (hasEdge) {
|
|
263
|
+
expect(newEdges.length, `${i}`).toBe(i >= pageLength ? pageLength : i + 1);
|
|
264
|
+
expect(newEdges[0], `${i}`).toStrictEqual(edges[i]);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
expect(newEdges.length, `${i}`).toBe(0);
|
|
268
|
+
}
|
|
269
|
+
if (hasPreviousPage) {
|
|
270
|
+
expect(pagination?.hasPreviousPage, `${i}`).toBe(true);
|
|
271
|
+
expect(pagination?.hasNextPage, `${i}`).toBe(false);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
expect(pagination?.hasPreviousPage, `${i}`).toBe(undefined);
|
|
275
|
+
expect(pagination?.hasNextPage, `${i}`).toBe(undefined);
|
|
276
|
+
}
|
|
277
|
+
if (cursor) {
|
|
278
|
+
verifyLastBeforeCursorQuery(query, 1, pageLength);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
verifyQuery(query, {
|
|
282
|
+
orderby: opts.orderby === "DESC" ? "ASC" : "DESC",
|
|
283
|
+
limit: pageLength,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function getCursor(edge) {
|
|
288
|
+
return query.getCursor(edge);
|
|
289
|
+
}
|
|
290
|
+
return { verify, getCursor };
|
|
291
|
+
}
|
|
245
292
|
if (opts.globalSchema) {
|
|
246
293
|
(0, ent_1.setGlobalSchema)(test_edge_global_schema_1.testEdgeGlobalSchema);
|
|
247
294
|
}
|
|
@@ -252,16 +299,8 @@ const commonTests = (opts) => {
|
|
|
252
299
|
});
|
|
253
300
|
}
|
|
254
301
|
beforeAll(async () => {
|
|
255
|
-
// want error on by default in tests?
|
|
256
|
-
(0, logger_1.setLogLevels)(["error", "warn", "info"]);
|
|
257
302
|
if (opts.livePostgresDB) {
|
|
258
|
-
tdb = await (0, test_helpers_1.setupTempDB)();
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
await (0, test_helpers_1.createEdges)();
|
|
262
|
-
});
|
|
263
|
-
beforeEach(async () => {
|
|
264
|
-
if (opts.livePostgresDB || opts.sqlite) {
|
|
303
|
+
tdb = await (0, test_helpers_1.setupTempDB)(opts.globalSchema);
|
|
265
304
|
return;
|
|
266
305
|
}
|
|
267
306
|
await (0, test_helpers_1.createEdges)();
|
|
@@ -278,14 +317,17 @@ const commonTests = (opts) => {
|
|
|
278
317
|
}, opts.newQuery, (contacts) => {
|
|
279
318
|
// nothing to do here
|
|
280
319
|
// reverse because edges are most recent first
|
|
281
|
-
|
|
320
|
+
if (opts.orderby === "DESC") {
|
|
321
|
+
return contacts.reverse();
|
|
322
|
+
}
|
|
323
|
+
return contacts;
|
|
282
324
|
}, getViewer());
|
|
283
325
|
beforeEach(async () => {
|
|
284
326
|
await filter.createData();
|
|
285
327
|
});
|
|
286
328
|
test("ids", async () => {
|
|
287
329
|
await filter.testIDs();
|
|
288
|
-
verifyQuery({});
|
|
330
|
+
verifyQuery(filter, {});
|
|
289
331
|
});
|
|
290
332
|
test("rawCount", async () => {
|
|
291
333
|
await filter.testRawCount();
|
|
@@ -293,15 +335,15 @@ const commonTests = (opts) => {
|
|
|
293
335
|
});
|
|
294
336
|
test("count", async () => {
|
|
295
337
|
await filter.testCount();
|
|
296
|
-
verifyQuery({});
|
|
338
|
+
verifyQuery(filter, {});
|
|
297
339
|
});
|
|
298
340
|
test("edges", async () => {
|
|
299
341
|
await filter.testEdges();
|
|
300
|
-
verifyQuery({});
|
|
342
|
+
verifyQuery(filter, {});
|
|
301
343
|
});
|
|
302
344
|
test("ents", async () => {
|
|
303
345
|
await filter.testEnts();
|
|
304
|
-
verifyQuery({ length: opts.entsLength });
|
|
346
|
+
verifyQuery(filter, { length: opts.entsLength });
|
|
305
347
|
});
|
|
306
348
|
test("all", async () => {
|
|
307
349
|
await filter.testAll();
|
|
@@ -330,11 +372,11 @@ const commonTests = (opts) => {
|
|
|
330
372
|
await action2.save();
|
|
331
373
|
}));
|
|
332
374
|
await action.save();
|
|
333
|
-
|
|
375
|
+
ml.clear();
|
|
334
376
|
});
|
|
335
377
|
test("ids", async () => {
|
|
336
378
|
await filter.testIDs();
|
|
337
|
-
verifyQuery({});
|
|
379
|
+
verifyQuery(filter, {});
|
|
338
380
|
});
|
|
339
381
|
test("rawCount", async () => {
|
|
340
382
|
await filter.testRawCount(0);
|
|
@@ -342,16 +384,16 @@ const commonTests = (opts) => {
|
|
|
342
384
|
});
|
|
343
385
|
test("count", async () => {
|
|
344
386
|
await filter.testCount(0);
|
|
345
|
-
verifyQuery({});
|
|
387
|
+
verifyQuery(filter, {});
|
|
346
388
|
});
|
|
347
389
|
test("edges", async () => {
|
|
348
390
|
await filter.testEdges();
|
|
349
|
-
verifyQuery({});
|
|
391
|
+
verifyQuery(filter, {});
|
|
350
392
|
});
|
|
351
393
|
test("ents", async () => {
|
|
352
394
|
await filter.testEnts();
|
|
353
395
|
// no ents so no subsequent query. just the edge query
|
|
354
|
-
verifyQuery({ length: 1 });
|
|
396
|
+
verifyQuery(filter, { length: 1 });
|
|
355
397
|
});
|
|
356
398
|
test("all", async () => {
|
|
357
399
|
await filter.testAll(0);
|
|
@@ -374,14 +416,17 @@ const commonTests = (opts) => {
|
|
|
374
416
|
// no filters
|
|
375
417
|
return q.first(N);
|
|
376
418
|
}, opts.newQuery, (contacts) => {
|
|
377
|
-
|
|
419
|
+
if (opts.orderby === "DESC") {
|
|
420
|
+
return contacts.reverse().slice(0, N);
|
|
421
|
+
}
|
|
422
|
+
return contacts.slice(0, N);
|
|
378
423
|
}, getViewer());
|
|
379
424
|
beforeEach(async () => {
|
|
380
425
|
await filter.createData();
|
|
381
426
|
});
|
|
382
427
|
test("ids", async () => {
|
|
383
428
|
await filter.testIDs();
|
|
384
|
-
verifyQuery({ limit: 2 });
|
|
429
|
+
verifyQuery(filter, { limit: 2 });
|
|
385
430
|
});
|
|
386
431
|
test("rawCount", async () => {
|
|
387
432
|
await filter.testRawCount();
|
|
@@ -389,15 +434,15 @@ const commonTests = (opts) => {
|
|
|
389
434
|
});
|
|
390
435
|
test("count", async () => {
|
|
391
436
|
await filter.testCount();
|
|
392
|
-
verifyQuery({ limit: 2 });
|
|
437
|
+
verifyQuery(filter, { limit: 2 });
|
|
393
438
|
});
|
|
394
439
|
test("edges", async () => {
|
|
395
440
|
await filter.testEdges();
|
|
396
|
-
verifyQuery({ limit: 2 });
|
|
441
|
+
verifyQuery(filter, { limit: 2 });
|
|
397
442
|
});
|
|
398
443
|
test("ents", async () => {
|
|
399
444
|
await filter.testEnts();
|
|
400
|
-
verifyQuery({ limit: 2, length: opts.entsLength });
|
|
445
|
+
verifyQuery(filter, { limit: 2, length: opts.entsLength });
|
|
401
446
|
});
|
|
402
447
|
test("all", async () => {
|
|
403
448
|
await filter.testAll();
|
|
@@ -415,15 +460,23 @@ const commonTests = (opts) => {
|
|
|
415
460
|
// no filters
|
|
416
461
|
return q.last(N);
|
|
417
462
|
}, opts.newQuery, (contacts) => {
|
|
418
|
-
|
|
419
|
-
|
|
463
|
+
if (opts.orderby === "DESC") {
|
|
464
|
+
return contacts.slice(0, N);
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
return contacts.reverse().slice(0, N);
|
|
468
|
+
}
|
|
420
469
|
}, getViewer());
|
|
470
|
+
const orderby = opts.orderby === "ASC" ? "DESC" : "ASC";
|
|
421
471
|
beforeEach(async () => {
|
|
422
472
|
await filter.createData();
|
|
423
473
|
});
|
|
424
474
|
test("ids", async () => {
|
|
425
475
|
await filter.testIDs();
|
|
426
|
-
verifyQuery({
|
|
476
|
+
verifyQuery(filter, {
|
|
477
|
+
orderby,
|
|
478
|
+
limit: N,
|
|
479
|
+
});
|
|
427
480
|
});
|
|
428
481
|
test("rawCount", async () => {
|
|
429
482
|
await filter.testRawCount();
|
|
@@ -431,15 +484,19 @@ const commonTests = (opts) => {
|
|
|
431
484
|
});
|
|
432
485
|
test("count", async () => {
|
|
433
486
|
await filter.testCount();
|
|
434
|
-
verifyQuery({
|
|
487
|
+
verifyQuery(filter, { orderby, limit: N });
|
|
435
488
|
});
|
|
436
489
|
test("edges", async () => {
|
|
437
490
|
await filter.testEdges();
|
|
438
|
-
verifyQuery({
|
|
491
|
+
verifyQuery(filter, { orderby, limit: N });
|
|
439
492
|
});
|
|
440
493
|
test("ents", async () => {
|
|
441
494
|
await filter.testEnts();
|
|
442
|
-
verifyQuery(
|
|
495
|
+
verifyQuery(filter, {
|
|
496
|
+
orderby,
|
|
497
|
+
limit: N,
|
|
498
|
+
length: opts.entsLength,
|
|
499
|
+
});
|
|
443
500
|
});
|
|
444
501
|
test("all", async () => {
|
|
445
502
|
await filter.testAll();
|
|
@@ -457,25 +514,23 @@ const commonTests = (opts) => {
|
|
|
457
514
|
const filter = new TestQueryFilter((q, user, contacts) => {
|
|
458
515
|
return q.first(N, getCursorFrom(contacts, idx));
|
|
459
516
|
}, opts.newQuery, (contacts) => {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
beforeAll(async () => {
|
|
464
|
-
if (opts.livePostgresDB || opts.sqlite) {
|
|
465
|
-
await filter.createData();
|
|
517
|
+
if (opts.orderby === "DESC") {
|
|
518
|
+
// < check so we shouldn't get that index
|
|
519
|
+
return contacts.reverse().slice(idx + 1, idx + N);
|
|
466
520
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
// should just delete this...
|
|
470
|
-
beforeEach(async () => {
|
|
471
|
-
if (opts.livePostgresDB || opts.sqlite) {
|
|
472
|
-
return;
|
|
521
|
+
else {
|
|
522
|
+
return contacts.slice(idx + 1, idx + N);
|
|
473
523
|
}
|
|
524
|
+
}, getViewer());
|
|
525
|
+
beforeAll(async () => {
|
|
474
526
|
await filter.createData();
|
|
475
527
|
});
|
|
528
|
+
beforeEach(() => {
|
|
529
|
+
ml.clear();
|
|
530
|
+
});
|
|
476
531
|
test("ids", async () => {
|
|
477
532
|
await filter.testIDs();
|
|
478
|
-
verifyFirstAfterCursorQuery();
|
|
533
|
+
verifyFirstAfterCursorQuery(filter);
|
|
479
534
|
});
|
|
480
535
|
test("rawCount", async () => {
|
|
481
536
|
await filter.testRawCount();
|
|
@@ -483,15 +538,15 @@ const commonTests = (opts) => {
|
|
|
483
538
|
});
|
|
484
539
|
test("count", async () => {
|
|
485
540
|
await filter.testCount();
|
|
486
|
-
verifyFirstAfterCursorQuery();
|
|
541
|
+
verifyFirstAfterCursorQuery(filter);
|
|
487
542
|
});
|
|
488
543
|
test("edges", async () => {
|
|
489
544
|
await filter.testEdges();
|
|
490
|
-
verifyFirstAfterCursorQuery();
|
|
545
|
+
verifyFirstAfterCursorQuery(filter);
|
|
491
546
|
});
|
|
492
547
|
test("ents", async () => {
|
|
493
548
|
await filter.testEnts();
|
|
494
|
-
verifyFirstAfterCursorQuery(opts.entsLength);
|
|
549
|
+
verifyFirstAfterCursorQuery(filter, opts.entsLength);
|
|
495
550
|
});
|
|
496
551
|
test("all", async () => {
|
|
497
552
|
await filter.testAll();
|
|
@@ -504,36 +559,15 @@ const commonTests = (opts) => {
|
|
|
504
559
|
});
|
|
505
560
|
});
|
|
506
561
|
test("first. after each cursor", async () => {
|
|
507
|
-
let [user
|
|
508
|
-
contacts = contacts.reverse();
|
|
562
|
+
let [user] = await (0, test_helpers_1.createAllContacts)();
|
|
509
563
|
const edges = await opts.newQuery(getViewer(), user).queryEdges();
|
|
510
|
-
|
|
511
|
-
async function verify(i, hasEdge, hasNextPage, cursor) {
|
|
512
|
-
query = opts.newQuery(getViewer(), user);
|
|
513
|
-
const newEdges = await query.first(1, cursor).queryEdges();
|
|
514
|
-
const pagination = query.paginationInfo().get(user.id);
|
|
515
|
-
if (hasEdge) {
|
|
516
|
-
expect(newEdges.length, `${i}`).toBe(1);
|
|
517
|
-
expect(newEdges[0], `${i}`).toStrictEqual(edges[i]);
|
|
518
|
-
}
|
|
519
|
-
else {
|
|
520
|
-
expect(newEdges.length, `${i}`).toBe(0);
|
|
521
|
-
}
|
|
522
|
-
if (hasNextPage) {
|
|
523
|
-
expect(pagination?.hasNextPage).toBe(true);
|
|
524
|
-
expect(pagination?.hasPreviousPage).toBe(false);
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
expect(pagination?.hasNextPage).toBe(undefined);
|
|
528
|
-
expect(pagination?.hasNextPage).toBe(undefined);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
564
|
+
const { verify, getCursor } = getVerifyAfterEachCursor(edges, 1, user);
|
|
531
565
|
await verify(0, true, true, undefined);
|
|
532
|
-
await verify(1, true, true,
|
|
533
|
-
await verify(2, true, true,
|
|
534
|
-
await verify(3, true, true,
|
|
535
|
-
await verify(4, true, false,
|
|
536
|
-
await verify(5, false, false,
|
|
566
|
+
await verify(1, true, true, getCursor(edges[0]));
|
|
567
|
+
await verify(2, true, true, getCursor(edges[1]));
|
|
568
|
+
await verify(3, true, true, getCursor(edges[2]));
|
|
569
|
+
await verify(4, true, false, getCursor(edges[3]));
|
|
570
|
+
await verify(5, false, false, getCursor(edges[4]));
|
|
537
571
|
});
|
|
538
572
|
describe("last. before cursor", () => {
|
|
539
573
|
const idx = 2;
|
|
@@ -542,23 +576,22 @@ const commonTests = (opts) => {
|
|
|
542
576
|
return q.last(N, getCursorFrom(contacts, idx));
|
|
543
577
|
}, opts.newQuery, (contacts) => {
|
|
544
578
|
// > check so we don't want that index
|
|
545
|
-
|
|
579
|
+
if (opts.orderby === "DESC") {
|
|
580
|
+
return contacts.reverse().slice(0, idx).reverse(); // because of order returned
|
|
581
|
+
}
|
|
582
|
+
return contacts.slice(0, idx).reverse(); // because of order returned
|
|
546
583
|
}, getViewer());
|
|
547
584
|
beforeAll(async () => {
|
|
548
585
|
if (opts.livePostgresDB || opts.sqlite) {
|
|
549
586
|
await filter.createData();
|
|
550
587
|
}
|
|
551
588
|
});
|
|
552
|
-
// same TODO above
|
|
553
589
|
beforeEach(async () => {
|
|
554
|
-
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
await filter.createData();
|
|
590
|
+
ml.clear();
|
|
558
591
|
});
|
|
559
592
|
test("ids", async () => {
|
|
560
593
|
await filter.testIDs();
|
|
561
|
-
verifyLastBeforeCursorQuery();
|
|
594
|
+
verifyLastBeforeCursorQuery(filter);
|
|
562
595
|
});
|
|
563
596
|
test("rawCount", async () => {
|
|
564
597
|
await filter.testRawCount();
|
|
@@ -566,15 +599,15 @@ const commonTests = (opts) => {
|
|
|
566
599
|
});
|
|
567
600
|
test("count", async () => {
|
|
568
601
|
await filter.testCount();
|
|
569
|
-
verifyLastBeforeCursorQuery();
|
|
602
|
+
verifyLastBeforeCursorQuery(filter);
|
|
570
603
|
});
|
|
571
604
|
test("edges", async () => {
|
|
572
605
|
await filter.testEdges();
|
|
573
|
-
verifyLastBeforeCursorQuery();
|
|
606
|
+
verifyLastBeforeCursorQuery(filter);
|
|
574
607
|
});
|
|
575
608
|
test("ents", async () => {
|
|
576
609
|
await filter.testEnts();
|
|
577
|
-
verifyLastBeforeCursorQuery(opts.entsLength);
|
|
610
|
+
verifyLastBeforeCursorQuery(filter, opts.entsLength);
|
|
578
611
|
});
|
|
579
612
|
test("all", async () => {
|
|
580
613
|
await filter.testAll();
|
|
@@ -587,36 +620,56 @@ const commonTests = (opts) => {
|
|
|
587
620
|
});
|
|
588
621
|
});
|
|
589
622
|
test("last. before each cursor", async () => {
|
|
590
|
-
let [user
|
|
591
|
-
contacts = contacts.reverse();
|
|
623
|
+
let [user] = await (0, test_helpers_1.createAllContacts)();
|
|
592
624
|
const edges = await opts.newQuery(getViewer(), user).queryEdges();
|
|
593
|
-
|
|
594
|
-
async function verify(i, hasEdge, hasPreviousPage, cursor) {
|
|
595
|
-
query = opts.newQuery(getViewer(), user);
|
|
596
|
-
const newEdges = await query.last(1, cursor).queryEdges();
|
|
597
|
-
const pagination = query.paginationInfo().get(user.id);
|
|
598
|
-
if (hasEdge) {
|
|
599
|
-
expect(newEdges.length, `${i}`).toBe(1);
|
|
600
|
-
expect(newEdges[0], `${i}`).toStrictEqual(edges[i]);
|
|
601
|
-
}
|
|
602
|
-
else {
|
|
603
|
-
expect(newEdges.length, `${i}`).toBe(0);
|
|
604
|
-
}
|
|
605
|
-
if (hasPreviousPage) {
|
|
606
|
-
expect(pagination?.hasPreviousPage).toBe(true);
|
|
607
|
-
expect(pagination?.hasNextPage).toBe(false);
|
|
608
|
-
}
|
|
609
|
-
else {
|
|
610
|
-
expect(pagination?.hasPreviousPage).toBe(undefined);
|
|
611
|
-
expect(pagination?.hasNextPage).toBe(undefined);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
625
|
+
const { verify, getCursor } = getVerifyBeforeEachCursor(edges, 1, user);
|
|
614
626
|
await verify(4, true, true, undefined);
|
|
615
|
-
await verify(3, true, true,
|
|
616
|
-
await verify(2, true, true,
|
|
617
|
-
await verify(1, true, true,
|
|
618
|
-
await verify(0, true, false,
|
|
619
|
-
await verify(-1, false, false,
|
|
627
|
+
await verify(3, true, true, getCursor(edges[4]));
|
|
628
|
+
await verify(2, true, true, getCursor(edges[3]));
|
|
629
|
+
await verify(1, true, true, getCursor(edges[2]));
|
|
630
|
+
await verify(0, true, false, getCursor(edges[1]));
|
|
631
|
+
await verify(-1, false, false, getCursor(edges[0]));
|
|
632
|
+
});
|
|
633
|
+
describe("with conflicts", () => {
|
|
634
|
+
let user;
|
|
635
|
+
let allEdges = [];
|
|
636
|
+
beforeEach(async () => {
|
|
637
|
+
const [u, contacts] = await (0, test_helpers_1.createAllContacts)();
|
|
638
|
+
user = u;
|
|
639
|
+
const [_, contacts2] = await (0, test_helpers_1.createAllContacts)({
|
|
640
|
+
user,
|
|
641
|
+
start: contacts[contacts.length - 1].createdAt.getTime() - 100,
|
|
642
|
+
});
|
|
643
|
+
await (0, test_helpers_1.createAllContacts)({
|
|
644
|
+
user,
|
|
645
|
+
start: contacts2[contacts.length - 1].createdAt.getTime() - 100,
|
|
646
|
+
});
|
|
647
|
+
const edges = await opts.newQuery(getViewer(), user).queryEdges();
|
|
648
|
+
// confirm there are duplicates...
|
|
649
|
+
expect(edges[4].created_at).toStrictEqual(edges[5].created_at);
|
|
650
|
+
expect(edges[9].created_at).toStrictEqual(edges[10].created_at);
|
|
651
|
+
allEdges = edges;
|
|
652
|
+
});
|
|
653
|
+
test("first after each cursor", async () => {
|
|
654
|
+
const { verify, getCursor } = getVerifyAfterEachCursor(allEdges, 5, user);
|
|
655
|
+
// regular pagination
|
|
656
|
+
await verify(0, true, true, undefined);
|
|
657
|
+
await verify(5, true, true, getCursor(allEdges[4]));
|
|
658
|
+
await verify(10, true, false, getCursor(allEdges[9]));
|
|
659
|
+
await verify(15, false, false, getCursor(allEdges[14]));
|
|
660
|
+
// one without duplicates work if we were paginating at a different place...
|
|
661
|
+
await verify(6, true, true, getCursor(allEdges[5]));
|
|
662
|
+
await verify(11, true, false, getCursor(allEdges[10]));
|
|
663
|
+
});
|
|
664
|
+
test("last before each cursor", async () => {
|
|
665
|
+
const { verify, getCursor } = getVerifyBeforeEachCursor(allEdges, 5, user);
|
|
666
|
+
await verify(14, true, true, undefined);
|
|
667
|
+
await verify(13, true, true, getCursor(allEdges[14]));
|
|
668
|
+
await verify(8, true, true, getCursor(allEdges[9]));
|
|
669
|
+
await verify(9, true, true, getCursor(allEdges[10]));
|
|
670
|
+
await verify(3, true, false, getCursor(allEdges[4]));
|
|
671
|
+
await verify(4, true, false, getCursor(allEdges[5]));
|
|
672
|
+
});
|
|
620
673
|
});
|
|
621
674
|
};
|
|
622
675
|
exports.commonTests = commonTests;
|