@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.
- package/dist/application.css +113 -24
- package/package.json +5 -3
- package/src/HonoAdapter.js +23 -23
- package/src/Logger.js +7 -8
- package/src/RaketaContext.js +1 -0
- package/src/cipher.js +2 -2
- package/src/cloud/ContentTasks.js +31 -0
- package/src/cloud/RaketaClient.js +1 -1
- package/src/cloud/Redirects.js +2 -2
- package/src/cloud/ResourceChanges.js +1 -1
- package/src/cloud/ResourceRevisions.js +2 -2
- package/src/cloud/Resources.js +28 -12
- package/src/cloud/Tags.js +4 -4
- package/src/cloud/documents/common.js +16 -0
- package/src/cloud/documents/contentTasksDocuments.js +59 -0
- package/src/cloud/documents/resourcesDocuments.js +12 -0
- package/src/filters.js +3 -3
- package/src/handlers/TagsHandler.js +2 -2
- package/src/handlers/_shared/getResourceUpdateDestination.js +1 -1
- package/src/handlers/categories/index.js +3 -3
- package/src/handlers/content_tasks/ContentTasksHandler.js +32 -0
- package/src/handlers/resource_revisions/LocksHandler.js +4 -1
- package/src/handlers/resources/ClonesHandler.js +1 -3
- package/src/handlers/resources/ExportsHandler.js +1 -5
- package/src/handlers/resources/ResourcesHandler.js +1 -1
- package/src/handlers/resources/TranslationsHandler.js +28 -19
- package/src/handlers/resources/URLsHandler.js +3 -1
- package/src/helpers/AuthHelper.js +1 -1
- package/src/helpers/FormBuilder.js +14 -14
- package/src/helpers/Pagination.js +5 -5
- package/src/helpers/historyUtils.js +3 -3
- package/src/helpers/utils.js +6 -1
- package/src/index.js +2 -1
- package/src/routeMember.js +9 -4
- package/src/routeNestedCollection.js +14 -29
- package/src/routeNestedMember.js +17 -6
- package/src/{routeResource.js → routeResourceModule.js} +25 -20
- package/src/routeStandard.js +8 -4
- package/src/setupAuthentication.js +1 -1
- package/src/setupCloud.js +5 -0
- package/src/tests/Adapter.test.js +2 -2
- package/src/tests/HonoAdapter.coverage.test.js +47 -25
- package/src/tests/HonoAdapter.filter.test.js +28 -18
- package/src/tests/HonoAdapter.test.js +3 -3
- package/src/tests/RaketaClient.test.js +427 -413
- package/src/tests/RaketaContext.test.js +1 -1
- package/src/tests/buildResourcePath.test.js +1 -1
- package/src/tests/cipher.test.js +16 -16
- package/src/tests/filters.test.js +24 -24
- package/src/tests/handlers/RedirectsHandler.test/destroy.test.js +1 -1
- package/src/tests/handlers/TagsHandler.test/create.test.js +2 -2
- package/src/tests/handlers/TagsHandler.test/destroy.test.js +1 -1
- package/src/tests/handlers/TagsHandler.test/update.test.js +2 -2
- package/src/tests/handlers/categories/create.test.js +2 -2
- package/src/tests/handlers/categories/destroy.test.js +1 -1
- package/src/tests/handlers/content_tasks/ContentTasksHandler.test/index.test.js +161 -0
- package/src/tests/handlers/resource_revisions/CancelSchedulesHandler.test/create.test.js +2 -2
- package/src/tests/handlers/resource_revisions/CodeHandler.test/update.test.js +1 -1
- package/src/tests/handlers/resource_revisions/GeneralHandler.test/update.test.js +1 -1
- package/src/tests/handlers/resource_revisions/LocksHandler.test/create.test.js +5 -5
- package/src/tests/handlers/resource_revisions/LocksHandler.test/create_form.test.js +6 -2
- package/src/tests/handlers/resource_revisions/MetaHandler.test/update.test.js +1 -1
- package/src/tests/handlers/resource_revisions/PublishesHandler.test/create.test.js +5 -5
- package/src/tests/handlers/resource_revisions/ResourceRevisionsHandler.test/create.test.js +2 -2
- package/src/tests/handlers/resource_revisions/ResourceRevisionsHandler.test/destroy.test.js +1 -1
- package/src/tests/handlers/resource_revisions/RevertsHandler.test/create.test.js +18 -3
- package/src/tests/handlers/resource_revisions/TagHandler.test/update.test.js +1 -1
- package/src/tests/handlers/resource_revisions/UnlocksHandler.test/create.test.js +2 -2
- package/src/tests/handlers/resource_revisions/VisualHandler.test/update.test.js +1 -1
- package/src/tests/handlers/resource_revisions/WidgetHandler.test/update.test.js +2 -2
- package/src/tests/handlers/resources/ChangeHandler.test/show.test.js +7 -2
- package/src/tests/handlers/resources/ClonesHandler.test/create.test.js +1 -3
- package/src/tests/handlers/resources/ExportsHandler.test/index.test.js +8 -8
- package/src/tests/handlers/resources/HistoryHandler.test/index.test.js +1 -1
- package/src/tests/handlers/resources/ResourcesAPIHandler.test/index.test.js +1 -5
- package/src/tests/handlers/resources/ResourcesHandler.test/create.test.js +2 -2
- package/src/tests/handlers/resources/ResourcesHandler.test/show.test.js +1 -1
- package/src/tests/handlers/resources/TranslationsHandler.test/create.test.js +24 -14
- package/src/tests/handlers/resources/TranslationsHandler.test/create_form.test.js +1 -1
- package/src/tests/handlers/resources/TranslationsHandler.test/index.test.js +3 -3
- package/src/tests/handlers/resources/URLsHandler.test/create.test.js +4 -6
- package/src/tests/helpers/AuthHelper.test.js +11 -12
- package/src/tests/helpers/CSVExportHelper.test.js +3 -3
- package/src/tests/helpers/FormBuilder.test.js +21 -21
- package/src/tests/helpers/HTMLBuilder.test.js +4 -4
- package/src/tests/helpers/Inflector.test.js +1 -1
- package/src/tests/helpers/Pagination.test.js +1 -1
- package/src/tests/helpers/utils.test.js +46 -0
- package/src/tests/routeCategoriesModule.test.js +10 -5
- package/src/tests/routeCollection.test.js +1 -1
- package/src/tests/routeMember.test.js +2 -2
- package/src/tests/routeNestedCollection.test.js +3 -3
- package/src/tests/routeNestedMember.test.js +3 -3
- package/src/tests/{routeResource.test.js → routeResourceModule.test.js} +28 -25
- package/src/tests/routeSettings.test.js +3 -3
- package/src/tests/routeStandard.test.js +31 -13
- package/src/tests/setupAuthentication.test.js +9 -6
- package/src/tests/support/factory.js +33 -0
- package/src/tests/utils.test.js +19 -19
- package/src/views/content_tasks/index.ejs +191 -0
- package/src/views/layouts/application.ejs +2 -1
- package/src/views/resources/_shared/_toolbar.ejs +33 -2
- package/src/views/resources/_shared/_translations_strip.ejs +71 -0
- package/src/views/resources/index.ejs +5 -0
- package/src/views/resources/show.ejs +1 -29
- 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
|
});
|
|
@@ -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(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
});
|
|
@@ -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
|
|
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("
|
|
11
|
+
describe("routeResourceModule", () => {
|
|
12
12
|
test("registers exports collection with explicit mapping", () => {
|
|
13
13
|
const adapter = makeAdapter();
|
|
14
14
|
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
81
|
+
routeResourceModule(adapter, "page", "pages");
|
|
79
82
|
|
|
80
|
-
const apiCollection = adapter.routeCollection.mock.calls.find(
|
|
81
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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].
|
|
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].
|
|
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
|
|
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("../
|
|
13
|
+
jest.mock("../routeResourceModule", () => jest.fn());
|
|
14
14
|
|
|
15
15
|
describe("routeStandard", () => {
|
|
16
16
|
beforeEach(() => {
|
|
17
17
|
routeCollection.mockClear();
|
|
18
18
|
routeSettings.mockClear();
|
|
19
|
-
|
|
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(
|
|
49
|
+
expect(routeCollection).toHaveBeenCalledWith(
|
|
50
|
+
adapter,
|
|
51
|
+
"redirects",
|
|
52
|
+
RedirectsHandler,
|
|
53
|
+
);
|
|
50
54
|
expect(routeCollection).toHaveBeenCalledWith(adapter, "tags", TagsHandler);
|
|
51
|
-
expect(routeCollection).toHaveBeenCalledWith(
|
|
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(
|
|
68
|
+
expect(routeResourceModule).toHaveBeenCalledWith(adapter, "page", "pages", {
|
|
61
69
|
dateFields: [],
|
|
62
70
|
});
|
|
63
|
-
expect(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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(
|
|
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,
|
package/src/tests/utils.test.js
CHANGED
|
@@ -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,
|
|
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,
|
|
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
|
+
});
|