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