@projectcaluma/ember-testing 9.1.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/mirage-graphql/filters/base.js +44 -17
- package/addon/mirage-graphql/filters/work-item.js +18 -0
- package/addon/mirage-graphql/handler.js +24 -6
- package/addon/mirage-graphql/index.js +24 -3
- package/addon/mirage-graphql/mocks/answer.js +11 -12
- package/addon/mirage-graphql/mocks/base.js +89 -30
- package/addon/mirage-graphql/mocks/form.js +7 -8
- package/addon/mirage-graphql/mocks/question.js +3 -75
- package/addon-mirage-support/factories/answer.js +2 -0
- package/addon-mirage-support/factories/case.js +1 -0
- package/addon-mirage-support/factories/document.js +4 -1
- package/addon-mirage-support/factories/file.js +1 -0
- package/addon-mirage-support/factories/form.js +3 -0
- package/addon-mirage-support/factories/format-validator.js +3 -0
- package/addon-mirage-support/factories/option.js +3 -0
- package/addon-mirage-support/factories/question.js +4 -0
- package/addon-mirage-support/factories/task.js +4 -3
- package/addon-mirage-support/factories/work-item.js +1 -0
- package/addon-mirage-support/models/question.js +1 -1
- package/addon-mirage-support/models/work-item.js +2 -0
- package/package.json +4 -4
- package/addon/mirage-graphql/mocks/case.js +0 -9
- package/addon/mirage-graphql/mocks/task.js +0 -55
- package/addon/mirage-graphql/resolvers/index.js +0 -16
- package/addon/mirage-graphql/serializers/answer.js +0 -14
- package/addon/mirage-graphql/serializers/base.js +0 -13
- package/addon/mirage-graphql/serializers/case.js +0 -11
- package/addon/mirage-graphql/serializers/document.js +0 -11
- package/addon/mirage-graphql/serializers/file.js +0 -12
- package/addon/mirage-graphql/serializers/form.js +0 -11
- package/addon/mirage-graphql/serializers/question.js +0 -14
- package/addon/mirage-graphql/serializers/task.js +0 -16
- package/addon/mirage-graphql/serializers/work-item.js +0 -11
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { camelize } from "@ember/string";
|
|
2
|
+
|
|
1
3
|
export default class {
|
|
2
4
|
constructor(type, collection, db) {
|
|
3
5
|
this.type = type;
|
|
@@ -5,35 +7,60 @@ export default class {
|
|
|
5
7
|
this.db = db;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
|
-
_getFilterFns(
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
_getFilterFns(rawFilters) {
|
|
11
|
+
const filters = Array.isArray(rawFilters)
|
|
12
|
+
? // new format
|
|
13
|
+
rawFilters.map((filter) => {
|
|
14
|
+
const entries = Object.entries(filter);
|
|
15
|
+
const key = entries[0][0];
|
|
16
|
+
const value = entries[0][1];
|
|
17
|
+
const options = entries
|
|
18
|
+
.slice(1)
|
|
19
|
+
.reduce((opts, [k, v]) => ({ ...opts, [k]: v }), {});
|
|
20
|
+
|
|
21
|
+
return { key, value, options };
|
|
22
|
+
})
|
|
23
|
+
: // old format
|
|
24
|
+
Object.entries(rawFilters).map(([key, value]) => ({
|
|
25
|
+
key,
|
|
26
|
+
value,
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
return filters.map(({ key, value, options = {} }) => {
|
|
30
|
+
const fn = this[key];
|
|
11
31
|
|
|
12
32
|
return typeof fn === "function"
|
|
13
|
-
? (records) => fn.call(this, records, value)
|
|
33
|
+
? (records) => fn.call(this, records, value, options)
|
|
14
34
|
: (records) => records;
|
|
15
35
|
});
|
|
16
36
|
}
|
|
17
37
|
|
|
38
|
+
sort(records, order) {
|
|
39
|
+
if (!order) return records;
|
|
40
|
+
|
|
41
|
+
return records.sort((a, b) => {
|
|
42
|
+
return (
|
|
43
|
+
order
|
|
44
|
+
.map((o) => {
|
|
45
|
+
const attr = camelize(o.attribute.toLowerCase());
|
|
46
|
+
const direction = o.direction === "ASC" ? -1 : 1;
|
|
47
|
+
|
|
48
|
+
return (b[attr] - a[attr]) * direction;
|
|
49
|
+
})
|
|
50
|
+
.find((result) => result !== 0) ?? 0
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
18
55
|
filter(records, filters) {
|
|
19
|
-
|
|
20
|
-
const filterObj = Array.isArray(filters)
|
|
21
|
-
? filters.length
|
|
22
|
-
? Object.assign(...filters)
|
|
23
|
-
: {}
|
|
24
|
-
: filters;
|
|
25
|
-
|
|
26
|
-
return this._getFilterFns(filterObj).reduce(
|
|
56
|
+
return this._getFilterFns(filters.filter ?? filters).reduce(
|
|
27
57
|
(recs, fn) => fn(recs),
|
|
28
|
-
records
|
|
58
|
+
this.sort(records, filters?.order)
|
|
29
59
|
);
|
|
30
60
|
}
|
|
31
61
|
|
|
32
62
|
find(records, filters) {
|
|
33
|
-
return (
|
|
34
|
-
this._getFilterFns(filters).reduce((recs, fn) => fn(recs), records)[0] ||
|
|
35
|
-
null
|
|
36
|
-
);
|
|
63
|
+
return this.filter(records, filters)[0] || null;
|
|
37
64
|
}
|
|
38
65
|
|
|
39
66
|
slug(records, value) {
|
|
@@ -4,4 +4,22 @@ export default class extends BaseFilter {
|
|
|
4
4
|
status(records, value) {
|
|
5
5
|
return records.filter(({ status }) => status === value);
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
task(records, value) {
|
|
9
|
+
const task = this.db.tasks.findBy({ slug: value });
|
|
10
|
+
|
|
11
|
+
return records.filter((record) => record.taskId === task?.id);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
controllingGroups(records, value, { invert = false }) {
|
|
15
|
+
return records.filter((record) =>
|
|
16
|
+
value.every((g) => invert !== record.controllingGroups.includes(g))
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
addressedGroups(records, value, { invert = false }) {
|
|
21
|
+
return records.filter((record) =>
|
|
22
|
+
value.every((g) => invert !== record.addressedGroups.includes(g))
|
|
23
|
+
);
|
|
24
|
+
}
|
|
7
25
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { classify } from "@ember/string";
|
|
2
2
|
import { singularize } from "ember-inflector";
|
|
3
3
|
import { graphql } from "graphql";
|
|
4
|
+
import {
|
|
5
|
+
GraphQLDate as Date,
|
|
6
|
+
GraphQLDateTime as DateTime,
|
|
7
|
+
} from "graphql-iso-date";
|
|
4
8
|
import { addMockFunctionsToSchema, makeExecutableSchema } from "graphql-tools";
|
|
5
|
-
import moment from "moment";
|
|
6
9
|
|
|
7
10
|
import { Mock } from "@projectcaluma/ember-testing/mirage-graphql";
|
|
8
|
-
import
|
|
9
|
-
import rawSchema from "@projectcaluma/ember-testing/mirage-graphql/schema.graphql";
|
|
11
|
+
import typeDefs from "@projectcaluma/ember-testing/mirage-graphql/schema.graphql";
|
|
10
12
|
|
|
11
13
|
export default function (server) {
|
|
12
14
|
return function ({ db }, request) {
|
|
@@ -18,8 +20,16 @@ export default function (server) {
|
|
|
18
20
|
}, {});
|
|
19
21
|
|
|
20
22
|
const schema = makeExecutableSchema({
|
|
21
|
-
typeDefs
|
|
22
|
-
resolvers
|
|
23
|
+
typeDefs,
|
|
24
|
+
resolvers: {
|
|
25
|
+
Date,
|
|
26
|
+
DateTime,
|
|
27
|
+
GenericScalar: {
|
|
28
|
+
serialize(value) {
|
|
29
|
+
return typeof value === "string" ? JSON.parse(value) : value;
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
23
33
|
resolverValidationOptions: { requireResolversForResolveType: false },
|
|
24
34
|
});
|
|
25
35
|
|
|
@@ -29,10 +39,18 @@ export default function (server) {
|
|
|
29
39
|
schema,
|
|
30
40
|
mocks: {
|
|
31
41
|
...mocks,
|
|
32
|
-
Date: () => moment().format(moment.HTML5_FMT.DATE),
|
|
33
42
|
JSONString: () => JSON.stringify({}),
|
|
34
43
|
GenericScalar: () => ({}),
|
|
35
44
|
Node: (_, { id }) => ({ __typename: atob(id).split(":")[0] }),
|
|
45
|
+
SelectedOption: ({ value }) => {
|
|
46
|
+
const option = server.schema.options.findBy({ slug: value });
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
slug: value,
|
|
50
|
+
label: option.label,
|
|
51
|
+
__typename: "SelectedOption",
|
|
52
|
+
};
|
|
53
|
+
},
|
|
36
54
|
},
|
|
37
55
|
preserveResolvers: false,
|
|
38
56
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dasherize } from "@ember/string";
|
|
1
|
+
import { dasherize, classify } from "@ember/string";
|
|
2
2
|
import require from "require";
|
|
3
3
|
|
|
4
4
|
const importTypeOrBase = (path, type) => {
|
|
@@ -28,8 +28,29 @@ export const register = (tpl) => (target, name, descriptor) => {
|
|
|
28
28
|
return descriptor;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
export const
|
|
32
|
-
|
|
31
|
+
export const serialize = (deserialized = {}, type) => {
|
|
32
|
+
const __typename = [deserialized.type?.toLowerCase(), type]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.map(classify)
|
|
35
|
+
.join("");
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
...deserialized,
|
|
39
|
+
id: btoa(`${__typename}:${deserialized.id}`),
|
|
40
|
+
__typename,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const deserialize = (serialized) => {
|
|
45
|
+
let decodedId = serialized.id;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
decodedId = atob(serialized.id).split(":")[1] || serialized.id;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// this is expected most times
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { ...serialized, ...(decodedId ? { id: decodedId } : {}) };
|
|
33
54
|
};
|
|
34
55
|
|
|
35
56
|
export const Filter = function (type, ...args) {
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import moment from "moment";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
register,
|
|
5
|
+
deserialize,
|
|
6
|
+
} from "@projectcaluma/ember-testing/mirage-graphql";
|
|
4
7
|
import BaseMock from "@projectcaluma/ember-testing/mirage-graphql/mocks/base";
|
|
5
8
|
|
|
6
9
|
export default class extends BaseMock {
|
|
7
|
-
@register("Answer")
|
|
8
|
-
handleAnswer({ __typename }) {
|
|
9
|
-
return { __typename };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
10
|
_handleSaveDocumentAnswer(
|
|
13
11
|
_,
|
|
14
12
|
{
|
|
@@ -38,8 +36,9 @@ export default class extends BaseMock {
|
|
|
38
36
|
if (res.answer.documentId) {
|
|
39
37
|
const doc = this.db.documents.findBy({ id: res.answer.documentId });
|
|
40
38
|
|
|
39
|
+
const { id } = deserialize(res.answer);
|
|
41
40
|
this.db.documents.update(doc.id, {
|
|
42
|
-
answerIds: [...new Set([...(doc.answerIds || []),
|
|
41
|
+
answerIds: [...new Set([...(doc.answerIds || []), id])],
|
|
43
42
|
});
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -51,7 +50,7 @@ export default class extends BaseMock {
|
|
|
51
50
|
handleSaveDocumentStringAnswer(_, { input }) {
|
|
52
51
|
return this._handleSaveDocumentAnswer(_, {
|
|
53
52
|
...input,
|
|
54
|
-
value: String(input.value),
|
|
53
|
+
value: input.value ? String(input.value) : null,
|
|
55
54
|
type: "STRING",
|
|
56
55
|
});
|
|
57
56
|
}
|
|
@@ -61,7 +60,7 @@ export default class extends BaseMock {
|
|
|
61
60
|
handleSaveIntegerAnswer(_, { input }) {
|
|
62
61
|
return this._handleSaveDocumentAnswer(_, {
|
|
63
62
|
...input,
|
|
64
|
-
value: parseInt(input.value),
|
|
63
|
+
value: input.value ? parseInt(input.value) : null,
|
|
65
64
|
type: "INTEGER",
|
|
66
65
|
});
|
|
67
66
|
}
|
|
@@ -71,7 +70,7 @@ export default class extends BaseMock {
|
|
|
71
70
|
handleSaveFloatAnswer(_, { input }) {
|
|
72
71
|
return this._handleSaveDocumentAnswer(_, {
|
|
73
72
|
...input,
|
|
74
|
-
value: parseFloat(input.value),
|
|
73
|
+
value: input.value ? parseFloat(input.value) : null,
|
|
75
74
|
type: "FLOAT",
|
|
76
75
|
});
|
|
77
76
|
}
|
|
@@ -81,7 +80,7 @@ export default class extends BaseMock {
|
|
|
81
80
|
handleSaveListAnswer(_, { input }) {
|
|
82
81
|
return this._handleSaveDocumentAnswer(_, {
|
|
83
82
|
...input,
|
|
84
|
-
value: [...input.value].map(String),
|
|
83
|
+
value: input.value ? [...input.value].map(String) : null,
|
|
85
84
|
type: "LIST",
|
|
86
85
|
});
|
|
87
86
|
}
|
|
@@ -90,7 +89,7 @@ export default class extends BaseMock {
|
|
|
90
89
|
handleSaveFileAnswer(_, { input }) {
|
|
91
90
|
return this._handleSaveDocumentAnswer(_, {
|
|
92
91
|
...input,
|
|
93
|
-
value: { metadata: { object_name: input.value } },
|
|
92
|
+
value: input.value ? { metadata: { object_name: input.value } } : null,
|
|
94
93
|
type: "FILE",
|
|
95
94
|
});
|
|
96
95
|
}
|
|
@@ -1,12 +1,54 @@
|
|
|
1
|
-
import { camelize, dasherize } from "@ember/string";
|
|
1
|
+
import { camelize, dasherize, classify } from "@ember/string";
|
|
2
|
+
import { singularize } from "ember-inflector";
|
|
2
3
|
import { MockList } from "graphql-tools";
|
|
3
4
|
|
|
4
5
|
import {
|
|
5
6
|
Filter,
|
|
6
|
-
Serializer,
|
|
7
7
|
register,
|
|
8
|
+
serialize,
|
|
9
|
+
deserialize,
|
|
8
10
|
} from "@projectcaluma/ember-testing/mirage-graphql";
|
|
9
11
|
|
|
12
|
+
export const ANSWER_TYPES = [
|
|
13
|
+
"DATE",
|
|
14
|
+
"FILE",
|
|
15
|
+
"FLOAT",
|
|
16
|
+
"INTEGER",
|
|
17
|
+
"LIST",
|
|
18
|
+
"STRING",
|
|
19
|
+
"TABLE",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export const QUESTION_TYPES = [
|
|
23
|
+
"ACTION_BUTTON",
|
|
24
|
+
"CALCULATED_FLOAT",
|
|
25
|
+
"CHOICE",
|
|
26
|
+
"DATE",
|
|
27
|
+
"DYNAMIC_CHOICE",
|
|
28
|
+
"DYNAMIC_MULTIPLE_CHOICE",
|
|
29
|
+
"FILE",
|
|
30
|
+
"FLOAT",
|
|
31
|
+
"FORM",
|
|
32
|
+
"INTEGER",
|
|
33
|
+
"MULTIPLE_CHOICE",
|
|
34
|
+
"STATIC",
|
|
35
|
+
"TABLE",
|
|
36
|
+
"TEXT",
|
|
37
|
+
"TEXTAREA",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export const TASK_TYPES = [
|
|
41
|
+
"SIMPLE",
|
|
42
|
+
"COMPLETE_WORKFLOW_FORM",
|
|
43
|
+
"COMPLETE_TASK_FORM",
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export const TYPE_MAPPING = {
|
|
47
|
+
Answer: ANSWER_TYPES,
|
|
48
|
+
Question: QUESTION_TYPES,
|
|
49
|
+
Task: TASK_TYPES,
|
|
50
|
+
};
|
|
51
|
+
|
|
10
52
|
export default class {
|
|
11
53
|
constructor(type, collection, db, server, ...args) {
|
|
12
54
|
this.type = type;
|
|
@@ -15,10 +57,10 @@ export default class {
|
|
|
15
57
|
this.server = server;
|
|
16
58
|
|
|
17
59
|
this.filter = new Filter(type, collection, db, server, ...args);
|
|
18
|
-
this.serializer = new Serializer(type, collection, db, server, ...args);
|
|
19
60
|
}
|
|
20
61
|
|
|
21
62
|
getHandlers() {
|
|
63
|
+
const types = TYPE_MAPPING[this.type];
|
|
22
64
|
const handlers = (target) => {
|
|
23
65
|
const proto = Reflect.getPrototypeOf(target);
|
|
24
66
|
const res = Object.values(proto);
|
|
@@ -37,10 +79,26 @@ export default class {
|
|
|
37
79
|
...handlers,
|
|
38
80
|
// Mocks can have multiple handlers per type.
|
|
39
81
|
...handler.__handlerFor.reduce((targets, target) => {
|
|
82
|
+
const handlerName = target.replace(/\{type\}/, this.type);
|
|
83
|
+
const baseHandlerName = handlerName.replace(/\{subtype\}/, "");
|
|
84
|
+
const fn = (...args) => handler.fn.apply(this, args);
|
|
85
|
+
|
|
86
|
+
const newHandlers = types
|
|
87
|
+
? types.reduce(
|
|
88
|
+
(typeHandlers, type) => ({
|
|
89
|
+
...typeHandlers,
|
|
90
|
+
[handlerName.replace(
|
|
91
|
+
/\{subtype\}/,
|
|
92
|
+
classify(type.toLowerCase())
|
|
93
|
+
)]: fn,
|
|
94
|
+
}),
|
|
95
|
+
{}
|
|
96
|
+
)
|
|
97
|
+
: { [baseHandlerName]: fn };
|
|
98
|
+
|
|
40
99
|
return {
|
|
41
100
|
...targets,
|
|
42
|
-
|
|
43
|
-
handler.fn.apply(this, args),
|
|
101
|
+
...newHandlers,
|
|
44
102
|
};
|
|
45
103
|
}, {}),
|
|
46
104
|
};
|
|
@@ -51,13 +109,10 @@ export default class {
|
|
|
51
109
|
}
|
|
52
110
|
|
|
53
111
|
@register("{type}Connection")
|
|
54
|
-
handleConnection(root, vars) {
|
|
55
|
-
let records = this.filter.filter(
|
|
56
|
-
this.collection,
|
|
57
|
-
this.serializer.deserialize(vars)
|
|
58
|
-
);
|
|
112
|
+
handleConnection(root, vars, _, { fieldName }) {
|
|
113
|
+
let records = this.filter.filter(this.collection, deserialize(vars));
|
|
59
114
|
|
|
60
|
-
const relKey = `${
|
|
115
|
+
const relKey = `${singularize(fieldName)}Ids`;
|
|
61
116
|
if (root && Object.prototype.hasOwnProperty.call(root, relKey)) {
|
|
62
117
|
const ids = root[relKey];
|
|
63
118
|
records = records.filter(({ id }) => ids && ids.includes(id));
|
|
@@ -91,40 +146,40 @@ export default class {
|
|
|
91
146
|
edges: () =>
|
|
92
147
|
new MockList(records.length, () => ({
|
|
93
148
|
node: (r, v, _, meta) =>
|
|
94
|
-
|
|
149
|
+
serialize(records[meta.path.prev.key], this.type),
|
|
95
150
|
})),
|
|
96
151
|
};
|
|
97
152
|
}
|
|
98
153
|
|
|
99
|
-
@register("{type}")
|
|
100
|
-
handle(root, vars) {
|
|
154
|
+
@register("{subtype}{type}")
|
|
155
|
+
handle(root, vars, _, { fieldName }) {
|
|
101
156
|
// If the parent node already resolved this branch in the graph, return it
|
|
102
157
|
// directly without mocking it
|
|
103
158
|
if (
|
|
104
159
|
root &&
|
|
105
|
-
|
|
160
|
+
fieldName !== "node" &&
|
|
161
|
+
Object.prototype.hasOwnProperty.call(root, fieldName)
|
|
106
162
|
) {
|
|
107
|
-
return root[
|
|
163
|
+
return root[fieldName];
|
|
108
164
|
}
|
|
109
165
|
|
|
110
166
|
// If the parent node provides an ID for this relation, filter our mock data
|
|
111
167
|
// with that given ID
|
|
168
|
+
const relKey = `${fieldName}Id`;
|
|
112
169
|
if (
|
|
113
170
|
root &&
|
|
114
|
-
|
|
171
|
+
fieldName !== "node" &&
|
|
172
|
+
Object.prototype.hasOwnProperty.call(root, relKey)
|
|
115
173
|
) {
|
|
116
|
-
vars = { id: root[
|
|
174
|
+
vars = { id: root[relKey] };
|
|
117
175
|
}
|
|
118
176
|
|
|
119
|
-
const record = this.filter.find(
|
|
120
|
-
this.collection,
|
|
121
|
-
this.serializer.deserialize(vars)
|
|
122
|
-
);
|
|
177
|
+
const record = this.filter.find(this.collection, deserialize(vars));
|
|
123
178
|
|
|
124
|
-
return record &&
|
|
179
|
+
return record && serialize(record, this.type);
|
|
125
180
|
}
|
|
126
181
|
|
|
127
|
-
@register("Save{type}Payload")
|
|
182
|
+
@register("Save{subtype}{type}Payload")
|
|
128
183
|
handleSavePayload(_, { input: { clientMutationId, slug, id, ...args } }) {
|
|
129
184
|
const identifier = slug ? { slug } : { id };
|
|
130
185
|
|
|
@@ -146,8 +201,9 @@ export default class {
|
|
|
146
201
|
const res = obj
|
|
147
202
|
? this.collection.update(obj.id, parsedArgs)
|
|
148
203
|
: this.collection.insert(
|
|
149
|
-
this.
|
|
150
|
-
|
|
204
|
+
this.server.build(
|
|
205
|
+
dasherize(this.type),
|
|
206
|
+
deserialize({
|
|
151
207
|
...identifier,
|
|
152
208
|
...parsedArgs,
|
|
153
209
|
})
|
|
@@ -155,10 +211,13 @@ export default class {
|
|
|
155
211
|
);
|
|
156
212
|
|
|
157
213
|
return {
|
|
158
|
-
[camelize(this.type)]:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
214
|
+
[camelize(this.type)]: serialize(
|
|
215
|
+
{
|
|
216
|
+
...relKeys.reduce((rels, key) => ({ ...rels, [key]: null }), {}),
|
|
217
|
+
...res,
|
|
218
|
+
},
|
|
219
|
+
this.type
|
|
220
|
+
),
|
|
162
221
|
clientMutationId,
|
|
163
222
|
};
|
|
164
223
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { MockList } from "graphql-tools";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
Serializer,
|
|
5
4
|
Filter,
|
|
6
5
|
register,
|
|
6
|
+
serialize,
|
|
7
7
|
} from "@projectcaluma/ember-testing/mirage-graphql";
|
|
8
8
|
import BaseMock from "@projectcaluma/ember-testing/mirage-graphql/mocks/base";
|
|
9
9
|
|
|
10
|
-
const questionSerializer = new Serializer("Question");
|
|
11
10
|
const questionFilter = new Filter("Question");
|
|
12
11
|
|
|
13
12
|
export default class extends BaseMock {
|
|
@@ -28,12 +27,12 @@ export default class extends BaseMock {
|
|
|
28
27
|
|
|
29
28
|
return {
|
|
30
29
|
form: {
|
|
31
|
-
...
|
|
30
|
+
...serialize(res, this.type),
|
|
32
31
|
questions: {
|
|
33
32
|
edges: () =>
|
|
34
33
|
new MockList(questions.length, () => ({
|
|
35
34
|
node: (r, v, _, meta) =>
|
|
36
|
-
|
|
35
|
+
serialize(questions[meta.path.prev.key], "Question"),
|
|
37
36
|
})),
|
|
38
37
|
},
|
|
39
38
|
},
|
|
@@ -64,12 +63,12 @@ export default class extends BaseMock {
|
|
|
64
63
|
|
|
65
64
|
return {
|
|
66
65
|
form: {
|
|
67
|
-
...
|
|
66
|
+
...serialize(res, this.type),
|
|
68
67
|
questions: {
|
|
69
68
|
edges: () =>
|
|
70
69
|
new MockList(questions.length, () => ({
|
|
71
70
|
node: (r, v, _, meta) =>
|
|
72
|
-
|
|
71
|
+
serialize(questions[meta.path.prev.key], "Question"),
|
|
73
72
|
})),
|
|
74
73
|
},
|
|
75
74
|
},
|
|
@@ -100,12 +99,12 @@ export default class extends BaseMock {
|
|
|
100
99
|
|
|
101
100
|
return {
|
|
102
101
|
form: {
|
|
103
|
-
...
|
|
102
|
+
...serialize(res, this.type),
|
|
104
103
|
questions: {
|
|
105
104
|
edges: () =>
|
|
106
105
|
new MockList(questions.length, () => ({
|
|
107
106
|
node: (r, v, _, meta) =>
|
|
108
|
-
|
|
107
|
+
serialize(questions[meta.path.prev.key], "Question"),
|
|
109
108
|
})),
|
|
110
109
|
},
|
|
111
110
|
},
|
|
@@ -1,87 +1,15 @@
|
|
|
1
|
-
import { classify } from "@ember/string";
|
|
2
1
|
import { MockList } from "graphql-tools";
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
Filter,
|
|
6
|
-
Serializer,
|
|
7
5
|
register,
|
|
6
|
+
serialize,
|
|
8
7
|
} from "@projectcaluma/ember-testing/mirage-graphql";
|
|
9
8
|
import BaseMock from "@projectcaluma/ember-testing/mirage-graphql/mocks/base";
|
|
10
9
|
|
|
11
10
|
const optionFilter = new Filter("Option");
|
|
12
|
-
const optionSerializer = new Serializer("Option");
|
|
13
11
|
|
|
14
12
|
export default class extends BaseMock {
|
|
15
|
-
@register("Question")
|
|
16
|
-
handleQuestion(root, ...args) {
|
|
17
|
-
const questionId =
|
|
18
|
-
root.questionId || (root.node && root.node(root, ...args).id);
|
|
19
|
-
let __typename = root.__typename;
|
|
20
|
-
|
|
21
|
-
if (questionId) {
|
|
22
|
-
__typename = `${classify(
|
|
23
|
-
this.collection.findBy({ id: questionId }).type.toLowerCase()
|
|
24
|
-
)}Question`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return { __typename };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
handleInterfaceType(root, vars, _, meta) {
|
|
31
|
-
return this.handle.fn.call(
|
|
32
|
-
this,
|
|
33
|
-
root,
|
|
34
|
-
{ ...vars, id: root.questionId },
|
|
35
|
-
_,
|
|
36
|
-
meta
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@register("TextQuestion")
|
|
41
|
-
handleTextQuestion(...args) {
|
|
42
|
-
return this.handleInterfaceType(...args);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@register("TextareaQuestion")
|
|
46
|
-
handleTextareaQuestion(...args) {
|
|
47
|
-
return this.handleInterfaceType(...args);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@register("IntegerQuestion")
|
|
51
|
-
handleIntegerQuestion(...args) {
|
|
52
|
-
return this.handleInterfaceType(...args);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@register("FloatQuestion")
|
|
56
|
-
handleFloatQuestion(...args) {
|
|
57
|
-
return this.handleInterfaceType(...args);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@register("MultipleChoiceQuestion")
|
|
61
|
-
handleMultipleChoiceQuestion(...args) {
|
|
62
|
-
return this.handleInterfaceType(...args);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@register("ChoiceQuestion")
|
|
66
|
-
handleChoiceQuestion(...args) {
|
|
67
|
-
return this.handleInterfaceType(...args);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
@register("FileQuestion")
|
|
71
|
-
handleFileQuestion(...args) {
|
|
72
|
-
return this.handleInterfaceType(...args);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
@register("StaticQuestion")
|
|
76
|
-
handleStaticQuestion(...args) {
|
|
77
|
-
return this.handleInterfaceType(...args);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@register("DateQuestion")
|
|
81
|
-
handleDateQuestion(...args) {
|
|
82
|
-
return this.handleInterfaceType(...args);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
13
|
@register("SaveTextQuestionPayload")
|
|
86
14
|
handleSaveTextQuestion(_, { input }) {
|
|
87
15
|
return this.handleSavePayload.fn.call(this, _, {
|
|
@@ -133,7 +61,7 @@ export default class extends BaseMock {
|
|
|
133
61
|
edges: () =>
|
|
134
62
|
new MockList(options.length, () => ({
|
|
135
63
|
node: (r, v, _, meta) =>
|
|
136
|
-
|
|
64
|
+
serialize(options[meta.path.prev.key], "Option"),
|
|
137
65
|
})),
|
|
138
66
|
},
|
|
139
67
|
});
|
|
@@ -157,7 +85,7 @@ export default class extends BaseMock {
|
|
|
157
85
|
edges: () =>
|
|
158
86
|
new MockList(options.length, () => ({
|
|
159
87
|
node: (r, v, _, meta) =>
|
|
160
|
-
|
|
88
|
+
serialize(options[meta.path.prev.key], "Option"),
|
|
161
89
|
})),
|
|
162
90
|
},
|
|
163
91
|
});
|
|
@@ -4,6 +4,7 @@ import faker from "faker";
|
|
|
4
4
|
const STATUS = ["RUNNING", "COMPLETED", "CANCELED", "SUSPENDED"];
|
|
5
5
|
|
|
6
6
|
export default Factory.extend({
|
|
7
|
+
id: () => faker.datatype.uuid(),
|
|
7
8
|
createdByUser: () => faker.datatype.uuid(),
|
|
8
9
|
createdAt: () => faker.date.past(),
|
|
9
10
|
modifiedAt: () => faker.date.past(),
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Factory } from "ember-cli-mirage";
|
|
2
2
|
import faker from "faker";
|
|
3
3
|
|
|
4
|
-
const TYPES = ["SIMPLE", "COMPLETE_WORKFLOW_FORM", "COMPLETE_TASK_FORM"];
|
|
5
|
-
|
|
6
4
|
export default Factory.extend({
|
|
5
|
+
id() {
|
|
6
|
+
return this.slug;
|
|
7
|
+
},
|
|
7
8
|
name: (i) => `Task #${i + 1}`,
|
|
8
9
|
slug: (i) => `task-${i + 1}`,
|
|
9
|
-
type:
|
|
10
|
+
type: "SIMPLE",
|
|
10
11
|
createdByUser: () => faker.datatype.uuid(),
|
|
11
12
|
createdAt: () => faker.date.past(),
|
|
12
13
|
});
|
|
@@ -4,6 +4,7 @@ import faker from "faker";
|
|
|
4
4
|
const STATUS = ["READY", "CANCELED", "COMPLETED", "SKIPPED", "SUSPENDED"];
|
|
5
5
|
|
|
6
6
|
export default Factory.extend({
|
|
7
|
+
id: () => faker.datatype.uuid(),
|
|
7
8
|
name: () => faker.lorem.words(5),
|
|
8
9
|
createdByUser: () => faker.datatype.uuid(),
|
|
9
10
|
createdAt: () => faker.date.past(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projectcaluma/ember-testing",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "Ember addon for testing with Caluma addons.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@ember/test-helpers": "2.6.0",
|
|
34
34
|
"@embroider/test-setup": "0.47.2",
|
|
35
35
|
"broccoli-asset-rev": "3.0.0",
|
|
36
|
-
"ember-cli": "3.28.
|
|
36
|
+
"ember-cli": "3.28.4",
|
|
37
37
|
"ember-cli-code-coverage": "1.0.3",
|
|
38
38
|
"ember-cli-dependency-checker": "3.2.0",
|
|
39
39
|
"ember-cli-inject-live-reload": "2.1.0",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"loader.js": "4.7.0",
|
|
54
54
|
"qunit": "2.17.2",
|
|
55
55
|
"qunit-dom": "2.0.0",
|
|
56
|
-
"webpack": "5.64.
|
|
56
|
+
"webpack": "5.64.1"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
|
-
"node": "
|
|
59
|
+
"node": "12.* || 14.* || >= 16"
|
|
60
60
|
},
|
|
61
61
|
"ember": {
|
|
62
62
|
"edition": "octane"
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { register } from "@projectcaluma/ember-testing/mirage-graphql";
|
|
2
|
-
import BaseMock from "@projectcaluma/ember-testing/mirage-graphql/mocks/base";
|
|
3
|
-
|
|
4
|
-
export default class extends BaseMock {
|
|
5
|
-
@register("Case")
|
|
6
|
-
handleCase({ __typename }) {
|
|
7
|
-
return { __typename };
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { classify } from "@ember/string";
|
|
2
|
-
|
|
3
|
-
import { register } from "@projectcaluma/ember-testing/mirage-graphql";
|
|
4
|
-
import BaseMock from "@projectcaluma/ember-testing/mirage-graphql/mocks/base";
|
|
5
|
-
|
|
6
|
-
export default class extends BaseMock {
|
|
7
|
-
@register("Task")
|
|
8
|
-
handleTask(root, vars, ...args) {
|
|
9
|
-
const serialized = this.handle.fn.call(this, root, vars);
|
|
10
|
-
|
|
11
|
-
let taskId =
|
|
12
|
-
root.taskId || (root.node && root.node(root, vars, ...args).id);
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
taskId = atob(taskId).split(":")[1];
|
|
16
|
-
} catch (e) {
|
|
17
|
-
// pass
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let __typename = root.__typename;
|
|
21
|
-
|
|
22
|
-
if (taskId) {
|
|
23
|
-
__typename = `${classify(
|
|
24
|
-
this.collection.findBy({ id: taskId }).type.toLowerCase()
|
|
25
|
-
)}Task`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return { ...serialized, __typename };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
handleInterfaceType(root, vars, _, meta) {
|
|
32
|
-
return this.handle.fn.call(
|
|
33
|
-
this,
|
|
34
|
-
root,
|
|
35
|
-
{ ...vars, id: root.taskId },
|
|
36
|
-
_,
|
|
37
|
-
meta
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@register("SimpleTask")
|
|
42
|
-
handleSimpleTask(...args) {
|
|
43
|
-
return this.handleInterfaceType(...args);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@register("CompleteWorkflowFormTask")
|
|
47
|
-
handleCompleteWorkflowForm(...args) {
|
|
48
|
-
return this.handleInterfaceType(...args);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@register("CompleteTaskFormTask")
|
|
52
|
-
handleCompleteTaskForm(...args) {
|
|
53
|
-
return this.handleInterfaceType(...args);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { GraphQLDate, GraphQLDateTime } from "graphql-iso-date";
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
Date: GraphQLDate,
|
|
5
|
-
DateTime: GraphQLDateTime,
|
|
6
|
-
// generic scalar serializes from a string to an object but deserializes as
|
|
7
|
-
// object because of backend limitations.
|
|
8
|
-
GenericScalar: {
|
|
9
|
-
serialize(str) {
|
|
10
|
-
return typeof str === "string" ? JSON.parse(str) : str;
|
|
11
|
-
},
|
|
12
|
-
deserialize(obj) {
|
|
13
|
-
return obj;
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { classify } from "@ember/string";
|
|
2
|
-
|
|
3
|
-
import BaseSerializer from "./base";
|
|
4
|
-
|
|
5
|
-
export default class extends BaseSerializer {
|
|
6
|
-
serialize(deserialized) {
|
|
7
|
-
const serialized = super.serialize(deserialized);
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
...serialized,
|
|
11
|
-
__typename: `${classify(serialized.type.toLowerCase())}Answer`,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import BaseSerializer from "./base";
|
|
2
|
-
|
|
3
|
-
export default class FileSerializer extends BaseSerializer {
|
|
4
|
-
serialize(deserialized) {
|
|
5
|
-
const serialized = super.serialize(deserialized);
|
|
6
|
-
|
|
7
|
-
return {
|
|
8
|
-
...serialized,
|
|
9
|
-
id: btoa(`File:${deserialized.id}`),
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { classify } from "@ember/string";
|
|
2
|
-
|
|
3
|
-
import BaseSerializer from "./base";
|
|
4
|
-
|
|
5
|
-
export default class extends BaseSerializer {
|
|
6
|
-
serialize(deserialized) {
|
|
7
|
-
const serialized = super.serialize(deserialized);
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
...serialized,
|
|
11
|
-
__typename: `${classify(serialized.type.toLowerCase())}Question`,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { classify } from "@ember/string";
|
|
2
|
-
|
|
3
|
-
import BaseSerializer from "./base";
|
|
4
|
-
|
|
5
|
-
export default class extends BaseSerializer {
|
|
6
|
-
serialize(deserialized) {
|
|
7
|
-
const serialized = super.serialize(deserialized);
|
|
8
|
-
const __typename = `${classify(serialized.type.toLowerCase())}Task`;
|
|
9
|
-
|
|
10
|
-
return {
|
|
11
|
-
...serialized,
|
|
12
|
-
id: btoa(`${__typename}:${deserialized.id}`),
|
|
13
|
-
__typename,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
}
|