@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.
Files changed (33) hide show
  1. package/addon/mirage-graphql/filters/base.js +44 -17
  2. package/addon/mirage-graphql/filters/work-item.js +18 -0
  3. package/addon/mirage-graphql/handler.js +24 -6
  4. package/addon/mirage-graphql/index.js +24 -3
  5. package/addon/mirage-graphql/mocks/answer.js +11 -12
  6. package/addon/mirage-graphql/mocks/base.js +89 -30
  7. package/addon/mirage-graphql/mocks/form.js +7 -8
  8. package/addon/mirage-graphql/mocks/question.js +3 -75
  9. package/addon-mirage-support/factories/answer.js +2 -0
  10. package/addon-mirage-support/factories/case.js +1 -0
  11. package/addon-mirage-support/factories/document.js +4 -1
  12. package/addon-mirage-support/factories/file.js +1 -0
  13. package/addon-mirage-support/factories/form.js +3 -0
  14. package/addon-mirage-support/factories/format-validator.js +3 -0
  15. package/addon-mirage-support/factories/option.js +3 -0
  16. package/addon-mirage-support/factories/question.js +4 -0
  17. package/addon-mirage-support/factories/task.js +4 -3
  18. package/addon-mirage-support/factories/work-item.js +1 -0
  19. package/addon-mirage-support/models/question.js +1 -1
  20. package/addon-mirage-support/models/work-item.js +2 -0
  21. package/package.json +4 -4
  22. package/addon/mirage-graphql/mocks/case.js +0 -9
  23. package/addon/mirage-graphql/mocks/task.js +0 -55
  24. package/addon/mirage-graphql/resolvers/index.js +0 -16
  25. package/addon/mirage-graphql/serializers/answer.js +0 -14
  26. package/addon/mirage-graphql/serializers/base.js +0 -13
  27. package/addon/mirage-graphql/serializers/case.js +0 -11
  28. package/addon/mirage-graphql/serializers/document.js +0 -11
  29. package/addon/mirage-graphql/serializers/file.js +0 -12
  30. package/addon/mirage-graphql/serializers/form.js +0 -11
  31. package/addon/mirage-graphql/serializers/question.js +0 -14
  32. package/addon/mirage-graphql/serializers/task.js +0 -16
  33. 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(filters) {
9
- return Object.entries(filters).map(([name, value]) => {
10
- const fn = this[name];
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
- // flatten array of filters to find filter functions
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 resolvers from "@projectcaluma/ember-testing/mirage-graphql/resolvers";
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: rawSchema,
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 Serializer = function (type, ...args) {
32
- return new (importTypeOrBase("./serializers", type))(type, ...args);
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 { register } from "@projectcaluma/ember-testing/mirage-graphql";
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 || []), res.answer.id])],
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
- [target.replace(/\{type\}/, this.type)]: (...args) =>
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 = `${camelize(this.type)}Ids`;
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
- this.serializer.serialize(records[meta.path.prev.key]),
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
- Object.prototype.hasOwnProperty.call(root, camelize(this.type))
160
+ fieldName !== "node" &&
161
+ Object.prototype.hasOwnProperty.call(root, fieldName)
106
162
  ) {
107
- return root[camelize(this.type)];
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
- Object.prototype.hasOwnProperty.call(root, `${camelize(this.type)}Id`)
171
+ fieldName !== "node" &&
172
+ Object.prototype.hasOwnProperty.call(root, relKey)
115
173
  ) {
116
- vars = { id: root[`${camelize(this.type)}Id`] };
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 && this.serializer.serialize(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.serializer.deserialize(
150
- this.server.build(dasherize(this.type), {
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)]: this.serializer.serialize({
159
- ...relKeys.reduce((rels, key) => ({ ...rels, [key]: null })),
160
- ...res,
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
- ...this.serializer.serialize(res),
30
+ ...serialize(res, this.type),
32
31
  questions: {
33
32
  edges: () =>
34
33
  new MockList(questions.length, () => ({
35
34
  node: (r, v, _, meta) =>
36
- questionSerializer.serialize(questions[meta.path.prev.key]),
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
- ...this.serializer.serialize(res),
66
+ ...serialize(res, this.type),
68
67
  questions: {
69
68
  edges: () =>
70
69
  new MockList(questions.length, () => ({
71
70
  node: (r, v, _, meta) =>
72
- questionSerializer.serialize(questions[meta.path.prev.key]),
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
- ...this.serializer.serialize(res),
102
+ ...serialize(res, this.type),
104
103
  questions: {
105
104
  edges: () =>
106
105
  new MockList(questions.length, () => ({
107
106
  node: (r, v, _, meta) =>
108
- questionSerializer.serialize(questions[meta.path.prev.key]),
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
- optionSerializer.serialize(options[meta.path.prev.key]),
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
- optionSerializer.serialize(options[meta.path.prev.key]),
88
+ serialize(options[meta.path.prev.key], "Option"),
161
89
  })),
162
90
  },
163
91
  });
@@ -3,6 +3,8 @@ import faker from "faker";
3
3
  import moment from "moment";
4
4
 
5
5
  export default Factory.extend({
6
+ id: () => faker.datatype.uuid(),
7
+
6
8
  afterCreate(answer, server) {
7
9
  if (!answer.question) {
8
10
  return;
@@ -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,3 +1,6 @@
1
1
  import { Factory } from "ember-cli-mirage";
2
+ import faker from "faker";
2
3
 
3
- export default Factory.extend({});
4
+ export default Factory.extend({
5
+ id: () => faker.datatype.uuid(),
6
+ });
@@ -2,6 +2,7 @@ import { Factory } from "ember-cli-mirage";
2
2
  import faker from "faker";
3
3
 
4
4
  export default Factory.extend({
5
+ id: () => faker.datatype.uuid(),
5
6
  createdAt: () => faker.date.past(),
6
7
  modifiedAt: () => faker.date.past(),
7
8
  createdByUser: () => faker.datatype.uuid(),
@@ -2,6 +2,9 @@ import { Factory } from "ember-cli-mirage";
2
2
  import faker from "faker";
3
3
 
4
4
  export default Factory.extend({
5
+ id() {
6
+ return this.slug;
7
+ },
5
8
  name: (i) => `Form #${i + 1}`,
6
9
  slug: (i) => `form-${i + 1}`,
7
10
  description: () => faker.lorem.paragraph(),
@@ -2,6 +2,9 @@ import { Factory } from "ember-cli-mirage";
2
2
  import faker from "faker";
3
3
 
4
4
  export default Factory.extend({
5
+ id() {
6
+ return this.slug;
7
+ },
5
8
  name: (i) => `Validator #${i + 1}`,
6
9
  slug: (i) => `validator-${i + 1}`,
7
10
  errorMsg: () => faker.lorem.paragraph(),
@@ -1,6 +1,9 @@
1
1
  import { Factory } from "ember-cli-mirage";
2
2
 
3
3
  export default Factory.extend({
4
+ id() {
5
+ return this.slug;
6
+ },
4
7
  slug: (i) => `option-${i + 1}`,
5
8
  label: (i) => `Option ${i + 1}`,
6
9
  meta: () => ({}),
@@ -2,6 +2,10 @@ import { Factory } from "ember-cli-mirage";
2
2
  import faker from "faker";
3
3
 
4
4
  export default Factory.extend({
5
+ id() {
6
+ return this.slug;
7
+ },
8
+
5
9
  type: "TEXT",
6
10
 
7
11
  slug: (i) => `question-${i + 1}`,
@@ -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: () => faker.random.arrayElement(TYPES),
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(),
@@ -3,5 +3,5 @@ import { Model, hasMany, belongsTo } from "ember-cli-mirage";
3
3
  export default Model.extend({
4
4
  forms: hasMany(),
5
5
  options: hasMany(),
6
- defaultAnswer: belongsTo("answer"),
6
+ defaultAnswer: belongsTo("answer", { inverse: null }),
7
7
  });
@@ -2,5 +2,7 @@ import { Model, belongsTo } from "ember-cli-mirage";
2
2
 
3
3
  export default Model.extend({
4
4
  case: belongsTo(),
5
+ childCase: belongsTo("case", { inverse: "parentWorkItem" }),
5
6
  task: belongsTo(),
7
+ document: belongsTo(),
6
8
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectcaluma/ember-testing",
3
- "version": "9.1.0",
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.3",
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.0"
56
+ "webpack": "5.64.1"
57
57
  },
58
58
  "engines": {
59
- "node": "10.* || >= 12"
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,13 +0,0 @@
1
- export default class {
2
- constructor(type) {
3
- this.type = type;
4
- }
5
-
6
- serialize(deserialized = {}) {
7
- return deserialized;
8
- }
9
-
10
- deserialize(serialized = {}) {
11
- return serialized;
12
- }
13
- }
@@ -1,11 +0,0 @@
1
- import BaseSerializer from "./base";
2
- export default class extends BaseSerializer {
3
- serialize(deserialized) {
4
- const serialized = super.serialize(deserialized);
5
-
6
- return {
7
- ...serialized,
8
- id: btoa(`Case:${deserialized.id}`),
9
- };
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import BaseSerializer from "./base";
2
- export default class extends BaseSerializer {
3
- serialize(deserialized) {
4
- const serialized = super.serialize(deserialized);
5
-
6
- return {
7
- ...serialized,
8
- id: btoa(`Document:${deserialized.id}`),
9
- };
10
- }
11
- }
@@ -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,11 +0,0 @@
1
- import BaseSerializer from "./base";
2
- export default class extends BaseSerializer {
3
- serialize(deserialized) {
4
- const serialized = super.serialize(deserialized);
5
-
6
- return {
7
- ...serialized,
8
- id: btoa(`Form:${deserialized.id}`),
9
- };
10
- }
11
- }
@@ -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
- }
@@ -1,11 +0,0 @@
1
- import BaseSerializer from "./base";
2
- export default class extends BaseSerializer {
3
- serialize(deserialized) {
4
- const serialized = super.serialize(deserialized);
5
-
6
- return {
7
- ...serialized,
8
- id: btoa(`WorkItem:${deserialized.id}`),
9
- };
10
- }
11
- }