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