@raketa-cloud/admin 1.8.9 → 1.8.11

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 (106) hide show
  1. package/dist/application.css +113 -24
  2. package/package.json +5 -3
  3. package/src/HonoAdapter.js +23 -23
  4. package/src/Logger.js +7 -8
  5. package/src/RaketaContext.js +1 -0
  6. package/src/cipher.js +2 -2
  7. package/src/cloud/ContentTasks.js +31 -0
  8. package/src/cloud/RaketaClient.js +1 -1
  9. package/src/cloud/Redirects.js +2 -2
  10. package/src/cloud/ResourceChanges.js +1 -1
  11. package/src/cloud/ResourceRevisions.js +2 -2
  12. package/src/cloud/Resources.js +28 -12
  13. package/src/cloud/Tags.js +4 -4
  14. package/src/cloud/documents/common.js +16 -0
  15. package/src/cloud/documents/contentTasksDocuments.js +59 -0
  16. package/src/cloud/documents/resourcesDocuments.js +12 -0
  17. package/src/filters.js +3 -3
  18. package/src/handlers/TagsHandler.js +2 -2
  19. package/src/handlers/_shared/getResourceUpdateDestination.js +1 -1
  20. package/src/handlers/categories/index.js +3 -3
  21. package/src/handlers/content_tasks/ContentTasksHandler.js +32 -0
  22. package/src/handlers/resource_revisions/LocksHandler.js +4 -1
  23. package/src/handlers/resources/ClonesHandler.js +1 -3
  24. package/src/handlers/resources/ExportsHandler.js +1 -5
  25. package/src/handlers/resources/ResourcesHandler.js +1 -1
  26. package/src/handlers/resources/TranslationsHandler.js +28 -19
  27. package/src/handlers/resources/URLsHandler.js +3 -1
  28. package/src/helpers/AuthHelper.js +1 -1
  29. package/src/helpers/FormBuilder.js +14 -14
  30. package/src/helpers/Pagination.js +5 -5
  31. package/src/helpers/historyUtils.js +3 -3
  32. package/src/helpers/utils.js +6 -1
  33. package/src/index.js +2 -1
  34. package/src/routeMember.js +9 -4
  35. package/src/routeNestedCollection.js +14 -29
  36. package/src/routeNestedMember.js +17 -6
  37. package/src/{routeResource.js → routeResourceModule.js} +25 -20
  38. package/src/routeStandard.js +8 -4
  39. package/src/setupAuthentication.js +1 -1
  40. package/src/setupCloud.js +5 -0
  41. package/src/tests/Adapter.test.js +2 -2
  42. package/src/tests/HonoAdapter.coverage.test.js +47 -25
  43. package/src/tests/HonoAdapter.filter.test.js +28 -18
  44. package/src/tests/HonoAdapter.test.js +3 -3
  45. package/src/tests/RaketaClient.test.js +427 -413
  46. package/src/tests/RaketaContext.test.js +1 -1
  47. package/src/tests/buildResourcePath.test.js +1 -1
  48. package/src/tests/cipher.test.js +16 -16
  49. package/src/tests/filters.test.js +24 -24
  50. package/src/tests/handlers/RedirectsHandler.test/destroy.test.js +1 -1
  51. package/src/tests/handlers/TagsHandler.test/create.test.js +2 -2
  52. package/src/tests/handlers/TagsHandler.test/destroy.test.js +1 -1
  53. package/src/tests/handlers/TagsHandler.test/update.test.js +2 -2
  54. package/src/tests/handlers/categories/create.test.js +2 -2
  55. package/src/tests/handlers/categories/destroy.test.js +1 -1
  56. package/src/tests/handlers/content_tasks/ContentTasksHandler.test/index.test.js +161 -0
  57. package/src/tests/handlers/resource_revisions/CancelSchedulesHandler.test/create.test.js +2 -2
  58. package/src/tests/handlers/resource_revisions/CodeHandler.test/update.test.js +1 -1
  59. package/src/tests/handlers/resource_revisions/GeneralHandler.test/update.test.js +1 -1
  60. package/src/tests/handlers/resource_revisions/LocksHandler.test/create.test.js +5 -5
  61. package/src/tests/handlers/resource_revisions/LocksHandler.test/create_form.test.js +6 -2
  62. package/src/tests/handlers/resource_revisions/MetaHandler.test/update.test.js +1 -1
  63. package/src/tests/handlers/resource_revisions/PublishesHandler.test/create.test.js +5 -5
  64. package/src/tests/handlers/resource_revisions/ResourceRevisionsHandler.test/create.test.js +2 -2
  65. package/src/tests/handlers/resource_revisions/ResourceRevisionsHandler.test/destroy.test.js +1 -1
  66. package/src/tests/handlers/resource_revisions/RevertsHandler.test/create.test.js +18 -3
  67. package/src/tests/handlers/resource_revisions/TagHandler.test/update.test.js +1 -1
  68. package/src/tests/handlers/resource_revisions/UnlocksHandler.test/create.test.js +2 -2
  69. package/src/tests/handlers/resource_revisions/VisualHandler.test/update.test.js +1 -1
  70. package/src/tests/handlers/resource_revisions/WidgetHandler.test/update.test.js +2 -2
  71. package/src/tests/handlers/resources/ChangeHandler.test/show.test.js +7 -2
  72. package/src/tests/handlers/resources/ClonesHandler.test/create.test.js +1 -3
  73. package/src/tests/handlers/resources/ExportsHandler.test/index.test.js +8 -8
  74. package/src/tests/handlers/resources/HistoryHandler.test/index.test.js +1 -1
  75. package/src/tests/handlers/resources/ResourcesAPIHandler.test/index.test.js +1 -5
  76. package/src/tests/handlers/resources/ResourcesHandler.test/create.test.js +2 -2
  77. package/src/tests/handlers/resources/ResourcesHandler.test/show.test.js +1 -1
  78. package/src/tests/handlers/resources/TranslationsHandler.test/create.test.js +24 -14
  79. package/src/tests/handlers/resources/TranslationsHandler.test/create_form.test.js +1 -1
  80. package/src/tests/handlers/resources/TranslationsHandler.test/index.test.js +3 -3
  81. package/src/tests/handlers/resources/URLsHandler.test/create.test.js +4 -6
  82. package/src/tests/helpers/AuthHelper.test.js +11 -12
  83. package/src/tests/helpers/CSVExportHelper.test.js +3 -3
  84. package/src/tests/helpers/FormBuilder.test.js +21 -21
  85. package/src/tests/helpers/HTMLBuilder.test.js +4 -4
  86. package/src/tests/helpers/Inflector.test.js +1 -1
  87. package/src/tests/helpers/Pagination.test.js +1 -1
  88. package/src/tests/helpers/utils.test.js +46 -0
  89. package/src/tests/routeCategoriesModule.test.js +10 -5
  90. package/src/tests/routeCollection.test.js +1 -1
  91. package/src/tests/routeMember.test.js +2 -2
  92. package/src/tests/routeNestedCollection.test.js +3 -3
  93. package/src/tests/routeNestedMember.test.js +3 -3
  94. package/src/tests/{routeResource.test.js → routeResourceModule.test.js} +28 -25
  95. package/src/tests/routeSettings.test.js +3 -3
  96. package/src/tests/routeStandard.test.js +31 -13
  97. package/src/tests/setupAuthentication.test.js +9 -6
  98. package/src/tests/support/factory.js +33 -0
  99. package/src/tests/utils.test.js +19 -19
  100. package/src/views/content_tasks/index.ejs +191 -0
  101. package/src/views/layouts/application.ejs +2 -1
  102. package/src/views/resources/_shared/_toolbar.ejs +33 -2
  103. package/src/views/resources/_shared/_translations_strip.ejs +71 -0
  104. package/src/views/resources/index.ejs +5 -0
  105. package/src/views/resources/show.ejs +1 -29
  106. package/src/views/resources/translations/create_form.ejs +13 -0
@@ -12,7 +12,7 @@ describe("HTMLBuilder", () => {
12
12
  const result = builder.tag("img", null, { src: "/some-image.jpg" });
13
13
 
14
14
  expect(normalizeHTML(result)).toEqual(
15
- normalizeHTML('<img src="/some-image.jpg" />')
15
+ normalizeHTML('<img src="/some-image.jpg" />'),
16
16
  );
17
17
  });
18
18
 
@@ -22,7 +22,7 @@ describe("HTMLBuilder", () => {
22
22
  const result = builder.tag("label", "Heelo", { for: "some-input-id" });
23
23
 
24
24
  expect(normalizeHTML(result)).toEqual(
25
- normalizeHTML('<label for="some-input-id">Heelo</label>')
25
+ normalizeHTML('<label for="some-input-id">Heelo</label>'),
26
26
  );
27
27
  });
28
28
 
@@ -33,11 +33,11 @@ describe("HTMLBuilder", () => {
33
33
  "textarea",
34
34
  undefined,
35
35
  { id: "some-input-id", value: "Text?" },
36
- { nonVoid: true }
36
+ { nonVoid: true },
37
37
  );
38
38
 
39
39
  expect(normalizeHTML(result)).toEqual(
40
- normalizeHTML('<textarea id="some-input-id" value="Text?"></textarea>')
40
+ normalizeHTML('<textarea id="some-input-id" value="Text?"></textarea>'),
41
41
  );
42
42
  });
43
43
  });
@@ -56,7 +56,7 @@ describe("Inflector", () => {
56
56
 
57
57
  test("handles mixed dashes and underscores", () => {
58
58
  expect(Inflector.humanize("hello_beautiful-world")).toBe(
59
- "hello beautiful world"
59
+ "hello beautiful world",
60
60
  );
61
61
  });
62
62
 
@@ -11,7 +11,7 @@ function buildPagination({ currentPage, pagesCount }) {
11
11
  query: {
12
12
  page: currentPage,
13
13
  },
14
- }
14
+ },
15
15
  );
16
16
  }
17
17
 
@@ -25,3 +25,49 @@ describe("includedInCollection", () => {
25
25
  expect(utils.includedInCollection("key", undefined)).toEqual(false);
26
26
  });
27
27
  });
28
+
29
+ describe("feature", () => {
30
+ it("returns true when the feature is enabled", () => {
31
+ const context = {
32
+ globalConfig: {
33
+ features: {
34
+ contentTasks: true,
35
+ },
36
+ },
37
+ };
38
+ expect(utils.feature("contentTasks", context)).toEqual(true);
39
+ });
40
+
41
+ it("returns false when the feature is disabled", () => {
42
+ const context = {
43
+ globalConfig: {
44
+ features: {
45
+ contentTasks: false,
46
+ },
47
+ },
48
+ };
49
+ expect(utils.feature("contentTasks", context)).toEqual(false);
50
+ });
51
+
52
+ it("returns false when the feature does not exist", () => {
53
+ const context = {
54
+ globalConfig: {
55
+ features: {},
56
+ },
57
+ };
58
+ expect(utils.feature("contentTasks", context)).toEqual(false);
59
+ });
60
+
61
+ it("returns false when globalConfig is undefined", () => {
62
+ const context = {};
63
+ expect(utils.feature("contentTasks", context)).toEqual(false);
64
+ });
65
+
66
+ it("returns false when context is undefined", () => {
67
+ expect(utils.feature("contentTasks", undefined)).toEqual(false);
68
+ });
69
+
70
+ it("returns false when context is null", () => {
71
+ expect(utils.feature("contentTasks", null)).toEqual(false);
72
+ });
73
+ });
@@ -14,10 +14,15 @@ describe("routeCategoriesModule", () => {
14
14
 
15
15
  routeCategoriesModule(adapter, "tag", "tags");
16
16
 
17
- expect(routeCollection).toHaveBeenCalledWith(adapter, "tags", CategoriesHandler, {
18
- categoryType: "tag",
19
- categoryTypePlural: "tags",
20
- views: "categories",
21
- });
17
+ expect(routeCollection).toHaveBeenCalledWith(
18
+ adapter,
19
+ "tags",
20
+ CategoriesHandler,
21
+ {
22
+ categoryType: "tag",
23
+ categoryTypePlural: "tags",
24
+ views: "categories",
25
+ },
26
+ );
22
27
  });
23
28
  });
@@ -65,7 +65,7 @@ describe("routeCollection", () => {
65
65
  UsersHandler.destroy,
66
66
  ],
67
67
  ],
68
- {}
68
+ {},
69
69
  );
70
70
  });
71
71
  });
@@ -51,7 +51,7 @@ describe("routeMember", () => {
51
51
  ProfileHandWithFilters.update,
52
52
  ],
53
53
  ],
54
- {}
54
+ {},
55
55
  );
56
56
  });
57
57
 
@@ -85,7 +85,7 @@ describe("routeMember", () => {
85
85
  ProfileHandWithFiltersWithFilters.update,
86
86
  ],
87
87
  ],
88
- {}
88
+ {},
89
89
  );
90
90
  });
91
91
  });
@@ -91,7 +91,7 @@ describe("routeNestedCollection", () => {
91
91
  OrdersHandler.destroy,
92
92
  ],
93
93
  ],
94
- {}
94
+ {},
95
95
  );
96
96
  });
97
97
 
@@ -100,7 +100,7 @@ describe("routeNestedCollection", () => {
100
100
  honoAdapter,
101
101
  "orders",
102
102
  "line_items",
103
- OrdersHandlerWithFilters
103
+ OrdersHandlerWithFilters,
104
104
  );
105
105
 
106
106
  expect(adapterSpy).toHaveBeenCalledWith(
@@ -162,7 +162,7 @@ describe("routeNestedCollection", () => {
162
162
  OrdersHandlerWithFilters.destroy,
163
163
  ],
164
164
  ],
165
- {}
165
+ {},
166
166
  );
167
167
  });
168
168
  });
@@ -51,7 +51,7 @@ describe("routeNestedMember", () => {
51
51
  ArtistHandWithFilters.update,
52
52
  ],
53
53
  ],
54
- {}
54
+ {},
55
55
  );
56
56
  });
57
57
 
@@ -60,7 +60,7 @@ describe("routeNestedMember", () => {
60
60
  honoAdapter,
61
61
  "artist",
62
62
  "bio",
63
- ArtistHandWithFiltersWithFilters
63
+ ArtistHandWithFiltersWithFilters,
64
64
  );
65
65
 
66
66
  expect(adapterSpy).toHaveBeenCalledWith(
@@ -90,7 +90,7 @@ describe("routeNestedMember", () => {
90
90
  ArtistHandWithFiltersWithFilters.update,
91
91
  ],
92
92
  ],
93
- {}
93
+ {},
94
94
  );
95
95
  });
96
96
  });
@@ -1,4 +1,4 @@
1
- import routeResource from "../routeResource";
1
+ import routeResourceModule from "../routeResourceModule";
2
2
 
3
3
  function makeAdapter() {
4
4
  return {
@@ -8,11 +8,11 @@ function makeAdapter() {
8
8
  };
9
9
  }
10
10
 
11
- describe("routeResource", () => {
11
+ describe("routeResourceModule", () => {
12
12
  test("registers exports collection with explicit mapping", () => {
13
13
  const adapter = makeAdapter();
14
14
 
15
- routeResource(adapter, "article", "articles", {
15
+ routeResourceModule(adapter, "article", "articles", {
16
16
  dateFields: ["publish_at"],
17
17
  });
18
18
 
@@ -38,7 +38,7 @@ describe("routeResource", () => {
38
38
  test("propagates resourceConfig with dateFields to all helpers", () => {
39
39
  const adapter = makeAdapter();
40
40
 
41
- routeResource(adapter, "event", "events", {
41
+ routeResourceModule(adapter, "event", "events", {
42
42
  dateFields: ["publish_at", "starts_at", "ends_at"],
43
43
  });
44
44
 
@@ -60,25 +60,28 @@ describe("routeResource", () => {
60
60
  test("registers ResourcesHandler collection at base resource", () => {
61
61
  const adapter = makeAdapter();
62
62
 
63
- routeResource(adapter, "page", "pages");
63
+ routeResourceModule(adapter, "page", "pages");
64
64
 
65
65
  const baseCollection = adapter.routeCollection.mock.calls.find(
66
- ([mapping]) => mapping.some(([, path]) => path === "/pages")
66
+ ([mapping]) => mapping.some(([, path]) => path === "/pages"),
67
67
  );
68
68
 
69
69
  expect(baseCollection).toBeDefined();
70
70
  expect(baseCollection[1]).toMatchObject({
71
- views: "resources",
71
+ dateFields: [],
72
+ resourceType: "page",
73
+ resourceTypePlural: "pages",
74
+ viewsFallback: "resources",
72
75
  });
73
76
  });
74
77
 
75
78
  test("registers api collection for resources", () => {
76
79
  const adapter = makeAdapter();
77
80
 
78
- routeResource(adapter, "page", "pages");
81
+ routeResourceModule(adapter, "page", "pages");
79
82
 
80
- const apiCollection = adapter.routeCollection.mock.calls.find(
81
- ([mapping]) => mapping.some(([, path]) => path === "/api/pages")
83
+ const apiCollection = adapter.routeCollection.mock.calls.find(([mapping]) =>
84
+ mapping.some(([, path]) => path === "/api/pages"),
82
85
  );
83
86
 
84
87
  expect(apiCollection).toBeDefined();
@@ -87,10 +90,10 @@ describe("routeResource", () => {
87
90
  test("registers nested collections for revisions, translations, history, locks, unlocks, clones, urls, deletes, publishes, cancel_schedules, reverts", () => {
88
91
  const adapter = makeAdapter();
89
92
 
90
- routeResource(adapter, "article", "articles");
93
+ routeResourceModule(adapter, "article", "articles");
91
94
 
92
95
  const nestedPaths = adapter.routeNestedCollection.mock.calls.flatMap(
93
- ([mapping]) => mapping.map(([, path]) => path)
96
+ ([mapping]) => mapping.map(([, path]) => path),
94
97
  );
95
98
 
96
99
  expect(nestedPaths).toEqual(
@@ -106,17 +109,17 @@ describe("routeResource", () => {
106
109
  "/articles/:parent_id/article_changes/reverts",
107
110
  "/article_revisions/:parent_id/publishes",
108
111
  "/article_revisions/:parent_id/cancel_schedules",
109
- ])
112
+ ]),
110
113
  );
111
114
  });
112
115
 
113
116
  test("registers nested members for general, visuals, codes, meta, tags", () => {
114
117
  const adapter = makeAdapter();
115
118
 
116
- routeResource(adapter, "article", "articles");
119
+ routeResourceModule(adapter, "article", "articles");
117
120
 
118
121
  const nestedMemberPaths = adapter.routeNestedMember.mock.calls.flatMap(
119
- ([mapping]) => mapping.map(([, path]) => path)
122
+ ([mapping]) => mapping.map(([, path]) => path),
120
123
  );
121
124
 
122
125
  expect(nestedMemberPaths).toEqual(
@@ -126,31 +129,31 @@ describe("routeResource", () => {
126
129
  "/article_revisions/:parent_id/codes",
127
130
  "/article_revisions/:parent_id/meta",
128
131
  "/article_revisions/:parent_id/tags",
129
- ])
132
+ ]),
130
133
  );
131
134
  });
132
135
 
133
136
  test("registers api widgets and change endpoints", () => {
134
137
  const adapter = makeAdapter();
135
138
 
136
- routeResource(adapter, "page", "pages");
139
+ routeResourceModule(adapter, "page", "pages");
137
140
 
138
141
  const nestedMemberPaths = adapter.routeNestedMember.mock.calls.flatMap(
139
- ([mapping]) => mapping.map(([, path]) => path)
142
+ ([mapping]) => mapping.map(([, path]) => path),
140
143
  );
141
144
 
142
145
  expect(nestedMemberPaths).toEqual(
143
146
  expect.arrayContaining([
144
147
  "/api/page_revisions/:parent_id/widgets",
145
148
  "/api/page/:parent_id/change",
146
- ])
149
+ ]),
147
150
  );
148
151
  });
149
152
 
150
153
  test("uses default empty dateFields when not provided", () => {
151
154
  const adapter = makeAdapter();
152
155
 
153
- routeResource(adapter, "page", "pages");
156
+ routeResourceModule(adapter, "page", "pages");
154
157
 
155
158
  const firstCall = adapter.routeCollection.mock.calls[0];
156
159
  expect(firstCall[1].dateFields).toEqual([]);
@@ -159,19 +162,19 @@ describe("routeResource", () => {
159
162
  test("propagates shared resources views for migrated collection helpers", () => {
160
163
  const adapter = makeAdapter();
161
164
 
162
- routeResource(adapter, "event", "events");
165
+ routeResourceModule(adapter, "event", "events");
163
166
 
164
167
  const baseCollection = adapter.routeCollection.mock.calls.find(
165
- ([mapping]) => mapping.some(([, path]) => path === "/events")
168
+ ([mapping]) => mapping.some(([, path]) => path === "/events"),
166
169
  );
167
170
 
168
- expect(baseCollection[1].views).toBe("resources");
171
+ expect(baseCollection[1].viewsFallback).toBe("resources");
169
172
 
170
173
  const translationsCall = adapter.routeNestedCollection.mock.calls.find(
171
174
  ([mapping]) =>
172
- mapping.some(([, path]) => path === "/events/:parent_id/translations")
175
+ mapping.some(([, path]) => path === "/events/:parent_id/translations"),
173
176
  );
174
177
 
175
- expect(translationsCall[1].views).toBe("resources/translations");
178
+ expect(translationsCall[1].viewsFallback).toBe("resources/translations");
176
179
  });
177
180
  });
@@ -20,21 +20,21 @@ describe("routeSettings", () => {
20
20
  adapter,
21
21
  "settings/meta",
22
22
  SettingsHandler,
23
- { resource: "settings/meta" }
23
+ { resource: "settings/meta" },
24
24
  );
25
25
  expect(routeMember).toHaveBeenNthCalledWith(
26
26
  2,
27
27
  adapter,
28
28
  "settings/layout",
29
29
  SettingsHandler,
30
- { resource: "settings/layout" }
30
+ { resource: "settings/layout" },
31
31
  );
32
32
  expect(routeMember).toHaveBeenNthCalledWith(
33
33
  3,
34
34
  adapter,
35
35
  "settings/variables",
36
36
  SettingsHandler,
37
- { resource: "settings/variables" }
37
+ { resource: "settings/variables" },
38
38
  );
39
39
  });
40
40
  });
@@ -1,7 +1,7 @@
1
1
  import routeStandard from "../routeStandard";
2
2
  import routeCollection from "../routeCollection";
3
3
  import routeSettings from "../routeSettings";
4
- import routeResource from "../routeResource";
4
+ import routeResourceModule from "../routeResourceModule";
5
5
 
6
6
  import DashboardsHandler from "../handlers/DashboardsHandler";
7
7
  import RedirectsHandler from "../handlers/RedirectsHandler";
@@ -10,13 +10,13 @@ import TagsAPIHandler from "../handlers/TagsAPIHandler";
10
10
 
11
11
  jest.mock("../routeCollection", () => jest.fn());
12
12
  jest.mock("../routeSettings", () => jest.fn());
13
- jest.mock("../routeResource", () => jest.fn());
13
+ jest.mock("../routeResourceModule", () => jest.fn());
14
14
 
15
15
  describe("routeStandard", () => {
16
16
  beforeEach(() => {
17
17
  routeCollection.mockClear();
18
18
  routeSettings.mockClear();
19
- routeResource.mockClear();
19
+ routeResourceModule.mockClear();
20
20
  });
21
21
 
22
22
  test("registers dashboard mapping via adapter.routeCollection", () => {
@@ -37,7 +37,7 @@ describe("routeStandard", () => {
37
37
  undefined,
38
38
  ],
39
39
  ],
40
- {}
40
+ {},
41
41
  );
42
42
  });
43
43
 
@@ -46,9 +46,17 @@ describe("routeStandard", () => {
46
46
 
47
47
  routeStandard(adapter);
48
48
 
49
- expect(routeCollection).toHaveBeenCalledWith(adapter, "redirects", RedirectsHandler);
49
+ expect(routeCollection).toHaveBeenCalledWith(
50
+ adapter,
51
+ "redirects",
52
+ RedirectsHandler,
53
+ );
50
54
  expect(routeCollection).toHaveBeenCalledWith(adapter, "tags", TagsHandler);
51
- expect(routeCollection).toHaveBeenCalledWith(adapter, "api/tags", TagsAPIHandler);
55
+ expect(routeCollection).toHaveBeenCalledWith(
56
+ adapter,
57
+ "api/tags",
58
+ TagsAPIHandler,
59
+ );
52
60
  });
53
61
 
54
62
  test("delegates to routeSettings and registers page/article/event resources", () => {
@@ -57,14 +65,24 @@ describe("routeStandard", () => {
57
65
  routeStandard(adapter);
58
66
 
59
67
  expect(routeSettings).toHaveBeenCalledWith(adapter);
60
- expect(routeResource).toHaveBeenCalledWith(adapter, "page", "pages", {
68
+ expect(routeResourceModule).toHaveBeenCalledWith(adapter, "page", "pages", {
61
69
  dateFields: [],
62
70
  });
63
- expect(routeResource).toHaveBeenCalledWith(adapter, "article", "articles", {
64
- dateFields: ["publish_at"],
65
- });
66
- expect(routeResource).toHaveBeenCalledWith(adapter, "event", "events", {
67
- dateFields: ["publish_at", "starts_at", "ends_at"],
68
- });
71
+ expect(routeResourceModule).toHaveBeenCalledWith(
72
+ adapter,
73
+ "article",
74
+ "articles",
75
+ {
76
+ dateFields: ["publish_at"],
77
+ },
78
+ );
79
+ expect(routeResourceModule).toHaveBeenCalledWith(
80
+ adapter,
81
+ "event",
82
+ "events",
83
+ {
84
+ dateFields: ["publish_at", "starts_at", "ends_at"],
85
+ },
86
+ );
69
87
  });
70
88
  });
@@ -87,12 +87,15 @@ describe("setupAuthentication", () => {
87
87
  expect(app.get).toHaveBeenCalledWith("/login", expect.any(Function));
88
88
  expect(app.get).toHaveBeenCalledWith(
89
89
  "/auth/google/callback",
90
- expect.any(Function)
90
+ expect.any(Function),
91
91
  );
92
92
  expect(app.get).toHaveBeenCalledWith("/logout", expect.any(Function));
93
93
  expect(app.get).toHaveBeenCalledWith("/profile", expect.any(Function));
94
94
  expect(app.get).toHaveBeenCalledWith("/remote/login", expect.any(Function));
95
- expect(app.post).toHaveBeenCalledWith("/remote/verify", expect.any(Function));
95
+ expect(app.post).toHaveBeenCalledWith(
96
+ "/remote/verify",
97
+ expect.any(Function),
98
+ );
96
99
  });
97
100
 
98
101
  describe("use middleware", () => {
@@ -156,7 +159,7 @@ describe("setupAuthentication", () => {
156
159
 
157
160
  expect(ctx.set).toHaveBeenCalledWith(
158
161
  "authentication",
159
- expect.objectContaining({ token: "header-token" })
162
+ expect.objectContaining({ token: "header-token" }),
160
163
  );
161
164
  });
162
165
  });
@@ -180,7 +183,7 @@ describe("setupAuthentication", () => {
180
183
 
181
184
  expect(ejs.renderFile).toHaveBeenCalledWith(
182
185
  expect.stringContaining("/views/_auth/login.ejs"),
183
- { googleURL: "https://google", error: "expired" }
186
+ { googleURL: "https://google", error: "expired" },
184
187
  );
185
188
  expect(ctx.html).toHaveBeenCalledWith("<html>login</html>");
186
189
  expect(result).toBe("htmled");
@@ -247,7 +250,7 @@ describe("setupAuthentication", () => {
247
250
  ctx,
248
251
  "raketa_token",
249
252
  "token",
250
- { path: "/", httpOnly: true, secure: false }
253
+ { path: "/", httpOnly: true, secure: false },
251
254
  );
252
255
  expect(ctx.redirect).toHaveBeenCalledWith("/remote/login");
253
256
  });
@@ -272,7 +275,7 @@ describe("setupAuthentication", () => {
272
275
  ctx,
273
276
  "raketa_token",
274
277
  "token",
275
- { path: "/", httpOnly: true, secure: true }
278
+ { path: "/", httpOnly: true, secure: true },
276
279
  );
277
280
  });
278
281
  });
@@ -75,6 +75,37 @@ const CATEGORY = {
75
75
  slug: "movie",
76
76
  };
77
77
 
78
+ const CONTENT_TASK = {
79
+ id: "1",
80
+ workflow: "lokalise",
81
+ operator: "7a456cdd-7278-4610-8b82-5b93cfcae396",
82
+ operatorMeta: {
83
+ name: "Jane Doe",
84
+ avatar: "",
85
+ },
86
+ completedAt: null,
87
+ failedAt: null,
88
+ rejectedAt: null,
89
+ insertedAt: "2024-08-30T19:05:00Z",
90
+ updatedAt: "2024-08-30T19:05:00Z",
91
+ resource: {
92
+ id: "123",
93
+ title: "Test Resource",
94
+ slug: "test-resource",
95
+ locale: "en",
96
+ visibility: "public",
97
+ resourceType: "page",
98
+ insertedAt: "2024-08-30T19:00:00Z",
99
+ updatedAt: "2024-08-30T19:05:00Z",
100
+ },
101
+ lokaliseWorkflow: null,
102
+ };
103
+
104
+ const EDITOR = {
105
+ id: "user-123",
106
+ name: "John Doe",
107
+ };
108
+
78
109
  const FIXTURES = {
79
110
  redirect: {
80
111
  id: "1",
@@ -97,6 +128,8 @@ const FIXTURES = {
97
128
  settings: { value: {} },
98
129
  tag: Tag,
99
130
  category: { ...CATEGORY },
131
+ contentTask: { ...CONTENT_TASK },
132
+ editor: { ...EDITOR },
100
133
  pagination: {
101
134
  currentPage: 1,
102
135
  pagesCount: 1,
@@ -2,7 +2,7 @@ import {
2
2
  toUTCISO8601String,
3
3
  dateToUTCISO8601String,
4
4
  toDateInput,
5
- toDateTimeInput
5
+ toDateTimeInput,
6
6
  } from "../utils";
7
7
 
8
8
  describe("utils", () => {
@@ -10,61 +10,61 @@ describe("utils", () => {
10
10
  test("converts datetime-local input to UTC ISO8601 string", () => {
11
11
  const inputDateTime = "2024-05-15T14:30";
12
12
  const expected = "2024-05-15T14:30:00Z";
13
-
13
+
14
14
  expect(toUTCISO8601String(inputDateTime)).toBe(expected);
15
15
  });
16
16
  });
17
-
17
+
18
18
  describe("dateToUTCISO8601String", () => {
19
19
  test("converts date input to UTC ISO8601 string with midnight time", () => {
20
20
  const inputDate = "2024-05-15";
21
21
  const expected = "2024-05-15T00:00:00Z";
22
-
22
+
23
23
  expect(dateToUTCISO8601String(inputDate)).toBe(expected);
24
24
  });
25
25
  });
26
-
26
+
27
27
  describe("toDateInput", () => {
28
28
  test("extracts date part from ISO8601 string", () => {
29
29
  const isoString = "2024-05-15T14:30:00Z";
30
30
  const expected = "2024-05-15";
31
-
31
+
32
32
  expect(toDateInput(isoString)).toBe(expected);
33
33
  });
34
-
34
+
35
35
  test("returns current date when no initial date is provided", () => {
36
36
  // Mock current date
37
37
  const mockDate = new Date(2024, 4, 15); // May 15, 2024
38
- jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
39
-
38
+ jest.spyOn(global, "Date").mockImplementation(() => mockDate);
39
+
40
40
  const expected = "2024-05-15";
41
-
41
+
42
42
  expect(toDateInput()).toBe(expected);
43
-
43
+
44
44
  // Restore Date
45
45
  jest.restoreAllMocks();
46
46
  });
47
47
  });
48
-
48
+
49
49
  describe("toDateTimeInput", () => {
50
50
  test("removes Z suffix from ISO8601 string", () => {
51
51
  const isoString = "2024-05-15T14:30:00Z";
52
52
  const expected = "2024-05-15T14:30:00";
53
-
53
+
54
54
  expect(toDateTimeInput(isoString)).toBe(expected);
55
55
  });
56
-
56
+
57
57
  test("returns current datetime when no initial date is provided", () => {
58
58
  // Mock current date
59
59
  const mockDate = new Date(2024, 4, 15, 14, 30); // May 15, 2024, 14:30
60
- jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
61
-
60
+ jest.spyOn(global, "Date").mockImplementation(() => mockDate);
61
+
62
62
  const expected = "2024-05-15T14:30";
63
-
63
+
64
64
  expect(toDateTimeInput()).toBe(expected);
65
-
65
+
66
66
  // Restore Date
67
67
  jest.restoreAllMocks();
68
68
  });
69
69
  });
70
- });
70
+ });