apostrophe 3.61.1 → 3.63.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 (104) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBar.vue +1 -1
  3. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +6 -4
  4. package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +9 -1
  5. package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +8 -0
  6. package/modules/@apostrophecms/area/ui/apos/components/AposWidgetControls.vue +6 -3
  7. package/modules/@apostrophecms/doc/index.js +256 -7
  8. package/modules/@apostrophecms/doc/ui/apos/mixins/AposFieldMetaUtilsMixin.js +93 -0
  9. package/modules/@apostrophecms/doc-type/index.js +78 -12
  10. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +9 -1
  11. package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +24 -6
  12. package/modules/@apostrophecms/i18n/i18n/en.json +1 -0
  13. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +8 -7
  14. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +1 -5
  15. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +5 -2
  16. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerSelections.vue +1 -5
  17. package/modules/@apostrophecms/image/ui/apos/components/AposMediaUploader.vue +4 -2
  18. package/modules/@apostrophecms/login/index.js +25 -19
  19. package/modules/@apostrophecms/login/ui/apos/components/AposLoginForm.vue +11 -1
  20. package/modules/@apostrophecms/login/ui/apos/logic/AposLoginForm.js +46 -2
  21. package/modules/@apostrophecms/modal/ui/apos/components/AposModalShareDraft.vue +8 -3
  22. package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +3 -0
  23. package/modules/@apostrophecms/page/index.js +118 -27
  24. package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +3 -1
  25. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +7 -0
  26. package/modules/@apostrophecms/page-type/index.js +81 -4
  27. package/modules/@apostrophecms/permission/index.js +60 -31
  28. package/modules/@apostrophecms/piece-type/index.js +19 -41
  29. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +9 -1
  30. package/modules/@apostrophecms/piece-type/ui/apos/components/AposUtilityOperations.vue +16 -1
  31. package/modules/@apostrophecms/rich-text-widget/index.js +141 -1
  32. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +8 -0
  33. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapImage.vue +7 -7
  34. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapLink.vue +38 -79
  35. package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Link.js +11 -0
  36. package/modules/@apostrophecms/schema/index.js +9 -0
  37. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +22 -2
  38. package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +1 -0
  39. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArea.vue +4 -1
  40. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +7 -8
  41. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +2 -0
  42. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +1 -0
  43. package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +1 -0
  44. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +76 -30
  45. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +2 -4
  46. package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +1 -1
  47. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +7 -0
  48. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +13 -1
  49. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +5 -1
  50. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +21 -0
  51. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +12 -8
  52. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputWrapper.js +35 -0
  53. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +6 -0
  54. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +41 -0
  55. package/modules/@apostrophecms/ui/ui/apos/components/AposCellContextMenu.vue +1 -0
  56. package/modules/@apostrophecms/ui/ui/apos/components/AposCheckbox.vue +1 -0
  57. package/modules/@apostrophecms/ui/ui/apos/components/AposTree.vue +7 -0
  58. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeRows.vue +8 -0
  59. package/modules/@apostrophecms/ui/ui/apos/mixins/AposPublishMixin.js +10 -4
  60. package/modules/@apostrophecms/ui/ui/apos/scss/global/_inputs.scss +2 -2
  61. package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +7 -0
  62. package/modules/@apostrophecms/widget-type/ui/apos/mixins/AposWidgetMixin.js +6 -0
  63. package/package.json +2 -2
  64. package/test/areas.js +1 -1
  65. package/test/assets.js +2 -2
  66. package/test/attachments.js +2 -2
  67. package/test/base-module.js +2 -1
  68. package/test/base-url-env-var.js +2 -2
  69. package/test/change-doc-ids.js +33 -31
  70. package/test/command-menu.js +2 -2
  71. package/test/content-i18n.js +47 -46
  72. package/test/db.js +2 -2
  73. package/test/docs.js +301 -126
  74. package/test/draft-published.js +2 -2
  75. package/test/email.js +2 -1
  76. package/test/express.js +3 -2
  77. package/test/external-front.js +4 -4
  78. package/test/field-meta.js +363 -0
  79. package/test/global.js +2 -1
  80. package/test/http.js +4 -2
  81. package/test/images.js +87 -88
  82. package/test/job.js +34 -34
  83. package/test/locks.js +2 -2
  84. package/test/login-requirements.js +3 -2
  85. package/test/middleware-and-route-order.js +2 -2
  86. package/test/page-type.js +2 -1
  87. package/test/pages-autocomplete.js +192 -0
  88. package/test/pages-public-api.js +2 -2
  89. package/test/pages-rest.js +4 -4
  90. package/test/pages.js +389 -57
  91. package/test/parked-pages.js +47 -47
  92. package/test/permissions.js +76 -0
  93. package/test/pieces-page-type.js +2 -1
  94. package/test/pieces-public-api.js +38 -38
  95. package/test/pieces.js +4 -4
  96. package/test/published-pages.js +16 -16
  97. package/test/rich-text-widget.js +164 -0
  98. package/test/schema-queryBuilders.js +180 -0
  99. package/test/schemaBuilders.js +4 -4
  100. package/test/schemas.js +220 -221
  101. package/test/search.js +2 -2
  102. package/test/soft-redirects.js +2 -1
  103. package/test/templates.js +2 -2
  104. package/test/users.js +2 -1
package/test/email.js CHANGED
@@ -1,9 +1,10 @@
1
1
  const t = require('../test-lib/test.js');
2
2
  const assert = require('assert').strict;
3
- let apos;
4
3
 
5
4
  describe('Email', function() {
6
5
 
6
+ let apos;
7
+
7
8
  this.timeout(t.timeout);
8
9
 
9
10
  after(async function() {
package/test/express.js CHANGED
@@ -1,10 +1,11 @@
1
1
  const t = require('../test-lib/test.js');
2
2
  const assert = require('assert');
3
- let jar;
4
- let apos;
5
3
 
6
4
  describe('Express', function() {
7
5
 
6
+ let jar;
7
+ let apos;
8
+
8
9
  this.timeout(t.timeout);
9
10
 
10
11
  it('express should exist on the apos object', async function() {
@@ -1,12 +1,12 @@
1
1
  const t = require('../test-lib/test.js');
2
2
  const assert = require('assert');
3
3
 
4
- let apos;
5
- // Set env var so these tests work even if you have a dev key in your bashrc etc.
6
- process.env.APOS_EXTERNAL_FRONT_KEY = 'this is a test external front key';
7
-
8
4
  describe('External Front', function() {
9
5
 
6
+ let apos;
7
+ // Set env var so these tests work even if you have a dev key in your bashrc etc.
8
+ process.env.APOS_EXTERNAL_FRONT_KEY = 'this is a test external front key';
9
+
10
10
  this.timeout(t.timeout);
11
11
 
12
12
  after(function() {
@@ -0,0 +1,363 @@
1
+ const t = require('../test-lib/test.js');
2
+ const assert = require('assert/strict');
3
+
4
+ describe('Field Meta', function () {
5
+ let apos;
6
+
7
+ this.timeout(t.timeout);
8
+
9
+ before(async function () {
10
+ apos = await t.create({
11
+ root: module,
12
+ modules: {}
13
+ });
14
+ });
15
+
16
+ after(function () {
17
+ return t.destroy(apos);
18
+ });
19
+
20
+ it('should validate arguments when getting meta path for a field', function () {
21
+ assert.throws(() => apos.doc.getMetaPath(), {
22
+ name: 'invalid',
23
+ data: {
24
+ cause: 'invalidArguments'
25
+ }
26
+ });
27
+ assert.throws(() => apos.doc.getMetaPath({}), {
28
+ name: 'invalid',
29
+ data: {
30
+ cause: 'subObjectNoId'
31
+ }
32
+ });
33
+ assert.throws(() => apos.doc.getMetaPath('string', 10), {
34
+ name: 'invalid',
35
+ data: {
36
+ cause: 'invalidArguments'
37
+ }
38
+ });
39
+ });
40
+
41
+ it('should get meta path for a field', function () {
42
+ assert.equal(apos.doc.getMetaPath('title'), 'title');
43
+ assert.equal(apos.doc.getMetaPath(undefined, 'title'), 'title');
44
+ assert.equal(apos.doc.getMetaPath(null, 'title'), 'title');
45
+ assert.equal(apos.doc.getMetaPath('address.city'), 'address.city');
46
+ assert.equal(apos.doc.getMetaPath('address', 'city'), 'address.aposMeta.city');
47
+ assert.equal(
48
+ apos.doc.getMetaPath('address', 'city', 'name'),
49
+ 'address.aposMeta.city.aposMeta.name'
50
+ );
51
+ assert.equal(
52
+ apos.doc.getMetaPath({ _id: 'someid' }),
53
+ '@someid'
54
+ );
55
+ assert.equal(
56
+ apos.doc.getMetaPath({ _id: 'someid' }, 'title'),
57
+ '@someid.aposMeta.title'
58
+ );
59
+ assert.equal(
60
+ apos.doc.getMetaPath({ _id: 'someid' }, 'address', 'city', 'name'),
61
+ '@someid.aposMeta.address.aposMeta.city.aposMeta.name'
62
+ );
63
+ assert.equal(
64
+ apos.doc.getMetaPath(undefined, 'address', null, 'city', undefined, 'name'),
65
+ 'address.aposMeta.city.aposMeta.name'
66
+ );
67
+ });
68
+
69
+ it('should validate arguments when setting meta value for a field', function () {
70
+ const doc = {};
71
+ const ns = 'a-module';
72
+ assert.throws(() => apos.doc.setMeta(), {
73
+ name: 'invalid',
74
+ data: {
75
+ cause: 'invalidArguments'
76
+ }
77
+ });
78
+ assert.throws(() => apos.doc.setMeta(doc, ns), {
79
+ name: 'invalid',
80
+ data: {
81
+ cause: 'invalidArguments'
82
+ }
83
+ });
84
+ assert.throws(() => apos.doc.setMeta(doc, ns, 'title'), {
85
+ name: 'invalid',
86
+ data: {
87
+ cause: 'invalidArguments'
88
+ }
89
+ });
90
+ assert.throws(() => apos.doc.setMeta(doc, ns, 'title', 'value'), {
91
+ name: 'invalid',
92
+ data: {
93
+ cause: 'invalidArguments'
94
+ }
95
+ });
96
+ assert.throws(() => apos.doc.setMeta(doc, ns, 10, 'key', 'value'), {
97
+ name: 'invalid',
98
+ data: {
99
+ cause: 'invalidArguments'
100
+ }
101
+ });
102
+ assert.throws(() => apos.doc.setMeta(doc, ns, 'title', 10, 'value'), {
103
+ name: 'invalid',
104
+ data: {
105
+ cause: 'invalidArguments'
106
+ }
107
+ });
108
+ assert.throws(() => apos.doc.setMeta(doc, ns, {}), {
109
+ name: 'invalid'
110
+ });
111
+ assert.throws(() => apos.doc.setMeta(doc, ns, {}, 'key', 'value'), {
112
+ name: 'invalid',
113
+ data: {
114
+ cause: 'subObjectNoId'
115
+ }
116
+ });
117
+ });
118
+
119
+ it('should set meta value for a field', function () {
120
+ const doc = {};
121
+ const ns = 'my-module';
122
+
123
+ apos.doc.setMeta(doc, ns, 'title', 'testKey', 'Hello');
124
+ apos.doc.setMeta(doc, ns, 'address.country', 'testKey', 'France');
125
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey', 'Paris');
126
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath', 'Dot path ignored');
127
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey', 'World');
128
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey', 'World');
129
+
130
+ assert.deepEqual(doc, {
131
+ aposMeta: {
132
+ title: { 'my-module:testKey': 'Hello' },
133
+ address: {
134
+ country: { 'my-module:testKey': 'France' },
135
+ aposMeta: {
136
+ city: {
137
+ aposMeta: {
138
+ name: {
139
+ 'my-module:testKey': 'Paris',
140
+ 'my-module:testKey.dotPath': 'Dot path ignored'
141
+ }
142
+ }
143
+ }
144
+ }
145
+ },
146
+ '@aWidgetOrArrayItemId': {
147
+ aposMeta: { title: { 'my-module:testKey': 'World' } },
148
+ 'my-module:testKey': 'World'
149
+ }
150
+ }
151
+ });
152
+ });
153
+
154
+ it('should validate arguments when getting meta value for a field', function () {
155
+ const doc = {};
156
+ const ns = 'a-module';
157
+
158
+ assert.throws(() => apos.doc.getMeta(), {
159
+ name: 'invalid',
160
+ data: {
161
+ cause: 'invalidArguments'
162
+ }
163
+ });
164
+ assert.throws(() => apos.doc.getMeta(doc, ns), {
165
+ name: 'invalid',
166
+ data: {
167
+ cause: 'invalidArguments'
168
+ }
169
+ });
170
+ assert.throws(() => apos.doc.getMeta(doc, ns, 'title'), {
171
+ name: 'invalid',
172
+ data: {
173
+ cause: 'invalidArguments'
174
+ }
175
+ });
176
+ assert.throws(() => apos.doc.getMeta(doc, ns, 10, 'key'), {
177
+ name: 'invalid',
178
+ data: {
179
+ cause: 'invalidArguments'
180
+ }
181
+ });
182
+ assert.throws(() => apos.doc.getMeta(doc, ns, 'title', 10), {
183
+ name: 'invalid',
184
+ data: {
185
+ cause: 'invalidArguments'
186
+ }
187
+ });
188
+ assert.throws(() => apos.doc.getMeta(doc, ns, {}), {
189
+ name: 'invalid',
190
+ data: {
191
+ cause: 'invalidArguments'
192
+ }
193
+ });
194
+ assert.throws(() => apos.doc.getMeta(doc, ns, {}, 'key'), {
195
+ name: 'invalid',
196
+ data: {
197
+ cause: 'subObjectNoId'
198
+ }
199
+ });
200
+ });
201
+
202
+ it('should get meta value for a field', function () {
203
+ const doc = {};
204
+ const ns = 'my-module';
205
+
206
+ apos.doc.setMeta(doc, ns, 'title', 'testKey', 'Hello');
207
+ assert.equal(apos.doc.getMeta(doc, ns, 'title', 'testKey'), 'Hello');
208
+
209
+ apos.doc.setMeta(doc, ns, 'address.country', 'testKey', 'France');
210
+ assert.equal(apos.doc.getMeta(doc, ns, 'address.country', 'testKey'), 'France');
211
+
212
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey', 'Paris');
213
+ assert.equal(apos.doc.getMeta(doc, ns, 'address', 'city', 'name', 'testKey'), 'Paris');
214
+
215
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath', 'Dot path ignored');
216
+ assert.equal(apos.doc.getMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath'), 'Dot path ignored');
217
+
218
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey', 'World');
219
+ assert.equal(apos.doc.getMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey'), 'World');
220
+
221
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey', 'World');
222
+ assert.equal(apos.doc.getMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey'), 'World');
223
+ });
224
+
225
+ it('should remove meta key for a field and cleanup', function () {
226
+ const doc = {
227
+ _id: 'doNotDeleteMe',
228
+ title: 'Do not delete me',
229
+ slug: 'do-not-delete-me'
230
+ };
231
+ const ns = 'my-module';
232
+
233
+ apos.doc.setMeta(doc, ns, 'title', 'testKey', 'Hello');
234
+ apos.doc.setMeta(doc, ns, 'address.country', 'testKey', 'France');
235
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey', 'Paris');
236
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath', 'Dot path ignored');
237
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey', 'World');
238
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey', 'World');
239
+
240
+ apos.doc.removeMeta(doc, ns, 'title', 'testKey');
241
+ assert.equal(apos.doc.getMeta(doc, ns, 'title', 'testKey'), undefined);
242
+
243
+ apos.doc.removeMeta(doc, ns, 'address.country', 'testKey');
244
+ assert.equal(apos.doc.getMeta(doc, ns, 'address.country', 'testKey'), undefined);
245
+
246
+ apos.doc.removeMeta(doc, ns, 'address', 'city', 'name', 'testKey');
247
+ assert.equal(apos.doc.getMeta(doc, ns, 'address', 'city', 'name', 'testKey'), undefined);
248
+
249
+ apos.doc.removeMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath');
250
+ assert.equal(apos.doc.getMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath'), undefined);
251
+
252
+ apos.doc.removeMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath');
253
+ assert.equal(apos.doc.getMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath'), undefined);
254
+
255
+ apos.doc.removeMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey');
256
+ assert.equal(apos.doc.getMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey'), undefined);
257
+
258
+ apos.doc.removeMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey');
259
+ assert.equal(apos.doc.getMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey'), undefined);
260
+
261
+ assert.deepEqual(doc, {
262
+ _id: 'doNotDeleteMe',
263
+ title: 'Do not delete me',
264
+ slug: 'do-not-delete-me',
265
+ aposMeta: {}
266
+ });
267
+ });
268
+
269
+ it('should be able to retrieve and manipulate meta by path', function () {
270
+
271
+ const doc = {};
272
+ const ns = 'my-module';
273
+
274
+ const titleMetaPath = apos.doc.getMetaPath('title');
275
+ const addressCountryMetaPath = apos.doc.getMetaPath('address.country');
276
+ const addressCityNameMetaPath = apos.doc.getMetaPath('address', 'city', 'name');
277
+ const addressCityNameDotPathMetaPath = apos.doc.getMetaPath('address', 'city', 'name');
278
+ const widgetMetaPath = apos.doc.getMetaPath({ _id: 'aWidgetOrArrayItemId' }, 'title');
279
+ const widgetTestKeyMetaPath = apos.doc.getMetaPath({ _id: 'aWidgetOrArrayItemId' });
280
+
281
+ apos.doc.setMeta(doc, ns, titleMetaPath, 'testKey', 'Hello');
282
+ apos.doc.setMeta(doc, ns, addressCountryMetaPath, 'testKey', 'France');
283
+ apos.doc.setMeta(doc, ns, addressCityNameMetaPath, 'testKey', 'Paris');
284
+ apos.doc.setMeta(doc, ns, addressCityNameDotPathMetaPath, 'testKey.dotPath', 'Dot path ignored');
285
+ apos.doc.setMeta(doc, ns, widgetMetaPath, 'testKey', 'World');
286
+ apos.doc.setMeta(doc, ns, widgetTestKeyMetaPath, 'testKey', 'World');
287
+
288
+ assert.equal(apos.doc.getMeta(doc, ns, titleMetaPath, 'testKey'), 'Hello');
289
+ assert.equal(apos.doc.getMeta(doc, ns, addressCountryMetaPath, 'testKey'), 'France');
290
+ assert.equal(apos.doc.getMeta(doc, ns, addressCityNameMetaPath, 'testKey'), 'Paris');
291
+ assert.equal(
292
+ apos.doc.getMeta(doc, ns, addressCityNameDotPathMetaPath, 'testKey.dotPath'),
293
+ 'Dot path ignored'
294
+ );
295
+ assert.equal(apos.doc.getMeta(doc, ns, widgetMetaPath, 'testKey'), 'World');
296
+ assert.equal(apos.doc.getMeta(doc, ns, widgetTestKeyMetaPath, 'testKey'), 'World');
297
+
298
+ assert.deepEqual(doc, {
299
+ aposMeta: {
300
+ title: { 'my-module:testKey': 'Hello' },
301
+ address: {
302
+ country: { 'my-module:testKey': 'France' },
303
+ aposMeta: {
304
+ city: {
305
+ aposMeta: {
306
+ name: {
307
+ 'my-module:testKey': 'Paris',
308
+ 'my-module:testKey.dotPath': 'Dot path ignored'
309
+ }
310
+ }
311
+ }
312
+ }
313
+ },
314
+ '@aWidgetOrArrayItemId': {
315
+ aposMeta: { title: { 'my-module:testKey': 'World' } },
316
+ 'my-module:testKey': 'World'
317
+ }
318
+ }
319
+ });
320
+
321
+ apos.doc.removeMeta(doc, ns, titleMetaPath, 'testKey');
322
+ apos.doc.removeMeta(doc, ns, addressCountryMetaPath, 'testKey');
323
+ apos.doc.removeMeta(doc, ns, addressCityNameMetaPath, 'testKey');
324
+ apos.doc.removeMeta(doc, ns, addressCityNameDotPathMetaPath, 'testKey.dotPath');
325
+ apos.doc.removeMeta(doc, ns, widgetMetaPath, 'testKey');
326
+ apos.doc.removeMeta(doc, ns, widgetTestKeyMetaPath, 'testKey');
327
+
328
+ assert.deepEqual(doc, {
329
+ aposMeta: {}
330
+ });
331
+ });
332
+
333
+ it('should retrieve meta keys for a field', function () {
334
+ const doc = {};
335
+ const ns = 'my-module';
336
+ const ns2 = 'other-module';
337
+
338
+ apos.doc.setMeta(doc, ns, 'title', 'testKey', 'Hello');
339
+ apos.doc.setMeta(doc, ns, 'title', 'testKey2', 'Hello');
340
+ apos.doc.setMeta(doc, ns2, 'title', 'testKey3', 'Hello');
341
+
342
+ apos.doc.setMeta(doc, ns, 'address.country', 'testKey', 'France');
343
+ apos.doc.setMeta(doc, ns2, 'address.country', 'testKey2', 'France');
344
+
345
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey', 'Paris');
346
+ apos.doc.setMeta(doc, ns2, 'address', 'city', 'name', 'testKey2', 'Paris');
347
+
348
+ apos.doc.setMeta(doc, ns, 'address', 'city', 'name', 'testKey.dotPath', 'Dot path ignored');
349
+ apos.doc.setMeta(doc, ns2, 'address', 'city', 'name', 'testKey2.dotPath', 'Dot path ignored');
350
+
351
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title', 'testKey', 'World');
352
+ apos.doc.setMeta(doc, ns2, { _id: 'aWidgetOrArrayItemId' }, 'title2', 'testKey', 'World');
353
+
354
+ apos.doc.setMeta(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'testKey', 'World');
355
+ apos.doc.setMeta(doc, ns2, { _id: 'aWidgetOrArrayItemId' }, 'testKey2S', 'World');
356
+
357
+ assert.deepEqual(apos.doc.getMetaKeys(doc, ns, 'title'), [ 'testKey', 'testKey2' ]);
358
+ assert.deepEqual(apos.doc.getMetaKeys(doc, ns, 'address.country'), [ 'testKey' ]);
359
+ assert.deepEqual(apos.doc.getMetaKeys(doc, ns, 'address', 'city', 'name'), [ 'testKey', 'testKey.dotPath' ]);
360
+ assert.deepEqual(apos.doc.getMetaKeys(doc, ns, { _id: 'aWidgetOrArrayItemId' }, 'title'), [ 'testKey' ]);
361
+ assert.deepEqual(apos.doc.getMetaKeys(doc, ns, { _id: 'aWidgetOrArrayItemId' }), [ 'testKey' ]);
362
+ });
363
+ });
package/test/global.js CHANGED
@@ -1,9 +1,10 @@
1
1
  const t = require('../test-lib/test.js');
2
2
  const assert = require('assert');
3
- let apos;
4
3
 
5
4
  describe('Global', function() {
6
5
 
6
+ let apos;
7
+
7
8
  this.timeout(t.timeout);
8
9
 
9
10
  after(function() {
package/test/http.js CHANGED
@@ -1,9 +1,11 @@
1
1
  const t = require('../test-lib/test.js');
2
2
  const assert = require('assert');
3
- let apos;
4
- let jar;
5
3
 
6
4
  describe('Http', function() {
5
+
6
+ let apos;
7
+ let jar;
8
+
7
9
  after(async function () {
8
10
  return t.destroy(apos);
9
11
  });
package/test/images.js CHANGED
@@ -4,54 +4,54 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const FormData = require('form-data');
6
6
 
7
- let apos;
8
- let jar;
9
- let inserted;
10
- let image;
11
-
12
- const mockImages = [
13
- {
14
- type: '@apostrophecms/image',
15
- slug: 'image-1',
16
- visibility: 'public',
17
- attachment: {
18
- extension: 'jpg',
19
- width: 500,
20
- height: 400
21
- }
22
- },
23
- {
24
- type: '@apostrophecms/image',
25
- slug: 'image-2',
26
- visibility: 'public',
27
- attachment: {
28
- extension: 'jpg',
29
- width: 500,
30
- height: 400
31
- }
32
- },
33
- {
34
- type: '@apostrophecms/image',
35
- slug: 'image-3',
36
- visibility: 'public',
37
- attachment: {
38
- extension: 'jpg',
39
- width: 150,
40
- height: 150
41
- }
42
- },
43
- {
44
- type: '@apostrophecms/image',
45
- slug: 'image-4',
46
- visibility: 'public',
47
- attachment: {
48
- extension: 'svg'
49
- }
50
- }
51
- ];
52
-
53
7
  describe('Images', function() {
54
8
 
9
+ let apos;
10
+ let jar;
11
+ let inserted;
12
+ let image;
13
+
14
+ const mockImages = [
15
+ {
16
+ type: '@apostrophecms/image',
17
+ slug: 'image-1',
18
+ visibility: 'public',
19
+ attachment: {
20
+ extension: 'jpg',
21
+ width: 500,
22
+ height: 400
23
+ }
24
+ },
25
+ {
26
+ type: '@apostrophecms/image',
27
+ slug: 'image-2',
28
+ visibility: 'public',
29
+ attachment: {
30
+ extension: 'jpg',
31
+ width: 500,
32
+ height: 400
33
+ }
34
+ },
35
+ {
36
+ type: '@apostrophecms/image',
37
+ slug: 'image-3',
38
+ visibility: 'public',
39
+ attachment: {
40
+ extension: 'jpg',
41
+ width: 150,
42
+ height: 150
43
+ }
44
+ },
45
+ {
46
+ type: '@apostrophecms/image',
47
+ slug: 'image-4',
48
+ visibility: 'public',
49
+ attachment: {
50
+ extension: 'svg'
51
+ }
52
+ }
53
+ ];
54
+
55
55
  this.timeout(t.timeout);
56
56
 
57
57
  after(function() {
@@ -263,53 +263,52 @@ describe('Images', function() {
263
263
  assert.strictEqual(fields.height, 225);
264
264
  });
265
265
 
266
- });
267
-
268
- async function insertUser(info) {
269
- const user = apos.user.newInstance();
270
- assert(user);
271
- Object.assign(user, info);
272
- await apos.user.insert(apos.task.getReq(), user);
273
- }
274
-
275
- async function login(username, password) {
276
- if (!password) {
277
- password = username;
266
+ async function insertUser(info) {
267
+ const user = apos.user.newInstance();
268
+ assert(user);
269
+ Object.assign(user, info);
270
+ await apos.user.insert(apos.task.getReq(), user);
278
271
  }
279
- jar = apos.http.jar();
280
272
 
281
- // establish session
282
- let page = await apos.http.get('/', {
283
- jar
284
- });
273
+ async function login(username, password) {
274
+ if (!password) {
275
+ password = username;
276
+ }
277
+ jar = apos.http.jar();
285
278
 
286
- assert(page.match(/logged out/));
279
+ // establish session
280
+ let page = await apos.http.get('/', {
281
+ jar
282
+ });
287
283
 
288
- // Log in
284
+ assert(page.match(/logged out/));
289
285
 
290
- await apos.http.post('/api/v1/@apostrophecms/login/login', {
291
- body: {
292
- username,
293
- password,
294
- session: true
295
- },
296
- jar
297
- });
286
+ // Log in
298
287
 
299
- // Confirm login
300
- page = await apos.http.get('/', {
301
- jar
302
- });
288
+ await apos.http.post('/api/v1/@apostrophecms/login/login', {
289
+ body: {
290
+ username,
291
+ password,
292
+ session: true
293
+ },
294
+ jar
295
+ });
303
296
 
304
- assert(page.match(/logged in/));
305
- return jar;
306
- }
297
+ // Confirm login
298
+ page = await apos.http.get('/', {
299
+ jar
300
+ });
307
301
 
308
- async function getEditableImages(jar) {
309
- return (await apos.http.post('/api/v1/@apostrophecms/doc/editable?aposMode=draft', {
310
- body: {
311
- ids: inserted.map(doc => doc._id.replace(':published', ':draft'))
312
- },
313
- jar
314
- })).editable;
315
- }
302
+ assert(page.match(/logged in/));
303
+ return jar;
304
+ }
305
+
306
+ async function getEditableImages(jar) {
307
+ return (await apos.http.post('/api/v1/@apostrophecms/doc/editable?aposMode=draft', {
308
+ body: {
309
+ ids: inserted.map(doc => doc._id.replace(':published', ':draft'))
310
+ },
311
+ jar
312
+ })).editable;
313
+ }
314
+ });