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