@raketa-cloud/admin 0.0.7 → 0.0.9
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/package.json +3 -2
- package/src/Adapter.js +3 -6
- package/src/cloud/ChangePageURL.js +24 -0
- package/src/cloud/ClonesPage.js +14 -0
- package/src/cloud/DeletePage.js +35 -0
- package/src/cloud/PageChanges.js +15 -0
- package/src/cloud/PageRevisions.js +135 -0
- package/src/cloud/PageTranslations.js +22 -0
- package/src/cloud/Pages.js +63 -0
- package/src/cloud/RaketaClient.js +118 -0
- package/src/cloud/Redirects.js +81 -0
- package/src/cloud/RevertPageRevision.js +18 -0
- package/src/cloud/Settings.js +30 -0
- package/src/cloud/Tags.js +80 -0
- package/src/cloud/documents/articlesDocuments.js +608 -0
- package/src/cloud/documents/categoryDocuments.js +64 -0
- package/src/cloud/documents/common.js +84 -0
- package/src/cloud/documents/pagesDocuments.js +245 -0
- package/src/cloud/documents/redirectsDocuments.js +82 -0
- package/src/cloud/documents/settingsDocuments.js +23 -0
- package/src/cloud/documents/tagsDocuments.js +63 -0
- package/src/currentPath.cjs +1 -0
- package/src/handlers/PageCloneHandler.js +17 -0
- package/src/handlers/PageCloneHandler.test/create.test.js +55 -0
- package/src/handlers/PageDeleteHandler.js +68 -0
- package/src/handlers/PageDeleteHandler.test/create.test.js +112 -0
- package/src/handlers/PageDeleteHandler.test/create_form.test.js +54 -0
- package/src/handlers/PageRevisionsCodesHandler.js +83 -0
- package/src/handlers/PageRevisionsCodesHandler.test/edit_form.test.js +56 -0
- package/src/handlers/PageRevisionsCodesHandler.test/update.test.js +137 -0
- package/src/handlers/PageRevisionsGeneralHandler.js +86 -0
- package/src/handlers/PageRevisionsGeneralHandler.test/edit_form.test.js +62 -0
- package/src/handlers/PageRevisionsGeneralHandler.test/update.test.js +147 -0
- package/src/handlers/PageRevisionsHandler.js +47 -0
- package/src/handlers/PageRevisionsHandler.test/create.test.js +67 -0
- package/src/handlers/PageRevisionsHandler.test/destroy.test.js +54 -0
- package/src/handlers/PageRevisionsLockHandler.js +54 -0
- package/src/handlers/PageRevisionsMetaHandler.js +83 -0
- package/src/handlers/PageRevisionsMetaHandler.test/edit_form.test.js +57 -0
- package/src/handlers/PageRevisionsMetaHandler.test/update.test.js +141 -0
- package/src/handlers/PageRevisionsTagsHandler.js +80 -0
- package/src/handlers/PageRevisionsTagsHandler.test/edit_form.test.js +69 -0
- package/src/handlers/PageRevisionsTagsHandler.test/update.test.js +141 -0
- package/src/handlers/PageRevisionsUnlockHandler.js +22 -0
- package/src/handlers/PageRevisionsVisualsHandler.js +77 -0
- package/src/handlers/PageRevisionsVisualsHandler.test/edit_form.test.js +55 -0
- package/src/handlers/PageRevisionsVisualsHandler.test/update.test.js +129 -0
- package/src/handlers/PageRevisionsWidgetsHandler.js +41 -0
- package/src/handlers/PageRevisionsWidgetsHandler.test/show.test.js +47 -0
- package/src/handlers/PageRevisionsWidgetsHandler.test/update.test.js +104 -0
- package/src/handlers/PageTranslationsHandler.js +91 -0
- package/src/handlers/PageURLsHandler.js +69 -0
- package/src/handlers/PageURLsHandler.test/create.test.js +157 -0
- package/src/handlers/PageURLsHandler.test/create_form.test.js +51 -0
- package/src/handlers/PagesHandler.js +114 -0
- package/src/handlers/PagesHandler.test/create.test.js +140 -0
- package/src/handlers/PagesHandler.test/create_form.test.js +41 -0
- package/src/handlers/PagesHandler.test/index.test.js +49 -0
- package/src/handlers/PagesHandler.test/show.test.js +103 -0
- package/src/handlers/PublishPageRevisionHandler.js +84 -0
- package/src/handlers/PublishPageRevisionHandler.test/create.test.js +136 -0
- package/src/handlers/PublishPageRevisionHandler.test/create_form.test.js +47 -0
- package/src/handlers/RedirectsHandler.js +124 -0
- package/src/handlers/RedirectsHandler.test/create.test.js +84 -0
- package/src/handlers/RedirectsHandler.test/create_form.test.js +29 -0
- package/src/handlers/RedirectsHandler.test/destroy.test.js +54 -0
- package/src/handlers/RedirectsHandler.test/edit_form.test.js +38 -0
- package/src/handlers/RedirectsHandler.test/index.test.js +42 -0
- package/src/handlers/RedirectsHandler.test/show.test.js +41 -0
- package/src/handlers/RedirectsHandler.test/update.test.js +89 -0
- package/src/handlers/RevertPageRevisionHandler.js +26 -0
- package/src/handlers/RevertPageRevisionHandler.test/create.test.js +80 -0
- package/src/handlers/SettingsGeneralHandler.js +13 -0
- package/src/handlers/SettingsLayoutHandler.js +51 -0
- package/src/handlers/SettingsMetaHandler.js +52 -0
- package/src/handlers/TagsHandler.js +113 -0
- package/src/helpers/FormBuilder.js +12 -4
- package/src/index.js +33 -0
- package/src/setupAuthentication.js +2 -5
- package/src/styles/application.css +55 -19
- package/src/views/layouts/application.ejs +30 -31
- package/src/views/layouts/header.ejs +5 -6
- package/src/views/page_deletes/create_form.ejs +55 -0
- package/src/views/page_lock/create_form.ejs +35 -0
- package/src/views/page_publish/_form.ejs +57 -0
- package/src/views/page_publish/create_form.ejs +11 -0
- package/src/views/page_revisions/_nav.ejs +40 -0
- package/src/views/page_revisions/codes/edit_form.ejs +39 -0
- package/src/views/page_revisions/general/edit_form.ejs +69 -0
- package/src/views/page_revisions/meta/edit_form.ejs +41 -0
- package/src/views/page_revisions/tags/edit_form.ejs +64 -0
- package/src/views/page_revisions/visuals/edit_form.ejs +42 -0
- package/src/views/page_translations/_form.ejs +76 -0
- package/src/views/page_translations/create_form.ejs +11 -0
- package/src/views/page_urls/create_form.ejs +31 -0
- package/src/views/pages/_form.ejs +84 -0
- package/src/views/pages/create_form.ejs +9 -0
- package/src/views/pages/edit_form.ejs +3 -0
- package/src/views/pages/index.ejs +161 -0
- package/src/views/pages/show.ejs +281 -0
- package/src/views/redirects/_form.ejs +40 -0
- package/src/views/redirects/create_form.ejs +9 -0
- package/src/views/redirects/edit_form.ejs +9 -0
- package/src/views/redirects/index.ejs +75 -1
- package/src/views/redirects/show.ejs +60 -0
- package/src/views/settings/_nav.ejs +28 -0
- package/src/views/settings/general/edit_form.ejs +26 -0
- package/src/views/settings/layout/edit_form.ejs +22 -0
- package/src/views/settings/meta/edit_form.ejs +38 -0
- package/src/views/tags/_form.ejs +39 -0
- package/src/views/tags/create_form.ejs +9 -0
- package/src/views/tags/edit_form.ejs +9 -0
- package/src/views/tags/index.ejs +43 -0
- package/test/factory.js +91 -0
- package/test/handlersHelper.js +9 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import PageRevisionsGeneralHandler from "../PageRevisionsGeneralHandler";
|
|
2
|
+
import PageRevisions from "../../cloud/PageRevisions";
|
|
3
|
+
import Pages from "../../cloud/Pages";
|
|
4
|
+
|
|
5
|
+
import { testConfig } from "../../../../../apps/admin/test/handlersHelper";
|
|
6
|
+
import Factory from "../../../../../apps/admin/test/factory";
|
|
7
|
+
|
|
8
|
+
function buildCtx(revision, updateSettings) {
|
|
9
|
+
return {
|
|
10
|
+
client: {
|
|
11
|
+
pageRevisions: new PageRevisions(testConfig, "token"),
|
|
12
|
+
pages: new Pages(testConfig, "token"),
|
|
13
|
+
},
|
|
14
|
+
params: { parent_id: revision.id },
|
|
15
|
+
resourceParams: {
|
|
16
|
+
general_settings: updateSettings,
|
|
17
|
+
},
|
|
18
|
+
locale: "en",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("Page revision general settings", () => {
|
|
23
|
+
test("update successful", async () => {
|
|
24
|
+
const revision = Factory.build("page_revision");
|
|
25
|
+
|
|
26
|
+
const updateSettings = {
|
|
27
|
+
title: "Updated title",
|
|
28
|
+
slug: "/updated-url",
|
|
29
|
+
visibility: "protected",
|
|
30
|
+
username: "user",
|
|
31
|
+
password: "admin123!@#",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
35
|
+
|
|
36
|
+
const mockFind = jest
|
|
37
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
38
|
+
.mockImplementation(() => revision);
|
|
39
|
+
|
|
40
|
+
const mockUpdate = jest
|
|
41
|
+
.spyOn(ctx.client.pageRevisions, "update")
|
|
42
|
+
.mockImplementation(() => ({
|
|
43
|
+
revision: {},
|
|
44
|
+
errors: null,
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const result = await PageRevisionsGeneralHandler.update(ctx);
|
|
48
|
+
|
|
49
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
50
|
+
expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", {
|
|
51
|
+
slug: updateSettings.slug,
|
|
52
|
+
title: updateSettings.title,
|
|
53
|
+
visibility: updateSettings.visibility,
|
|
54
|
+
widgets: JSON.stringify(revision.widgets),
|
|
55
|
+
tags: revision.tags.map((t) => t.id),
|
|
56
|
+
categories: revision.categories.map((c) => c.id),
|
|
57
|
+
settings: JSON.stringify({
|
|
58
|
+
...revision.settings,
|
|
59
|
+
credentials: {
|
|
60
|
+
user: updateSettings.username,
|
|
61
|
+
password: updateSettings.password,
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(result).toEqual({
|
|
67
|
+
redirect: `/en/page_revisions/${revision.id}/general/edit`,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("update failed", async () => {
|
|
72
|
+
const revision = Factory.build("page_revision");
|
|
73
|
+
|
|
74
|
+
const updateSettings = {
|
|
75
|
+
title: "Updated title",
|
|
76
|
+
slug: "/updated-url",
|
|
77
|
+
visibility: "protected",
|
|
78
|
+
username: "user",
|
|
79
|
+
password: "admin123!@#",
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
83
|
+
|
|
84
|
+
const mockFind = jest
|
|
85
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
86
|
+
.mockImplementation(() => revision);
|
|
87
|
+
|
|
88
|
+
const mockUpdate = jest
|
|
89
|
+
.spyOn(ctx.client.pageRevisions, "update")
|
|
90
|
+
.mockImplementation(() => ({
|
|
91
|
+
revision: {},
|
|
92
|
+
errors: [{ key: "slug", message: "has invalid format" }],
|
|
93
|
+
}));
|
|
94
|
+
|
|
95
|
+
const result = await PageRevisionsGeneralHandler.update(ctx);
|
|
96
|
+
|
|
97
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
98
|
+
expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", {
|
|
99
|
+
slug: updateSettings.slug,
|
|
100
|
+
title: updateSettings.title,
|
|
101
|
+
visibility: updateSettings.visibility,
|
|
102
|
+
widgets: JSON.stringify(revision.widgets),
|
|
103
|
+
tags: revision.tags.map((t) => t.id),
|
|
104
|
+
categories: revision.categories.map((c) => c.id),
|
|
105
|
+
settings: JSON.stringify({
|
|
106
|
+
...revision.settings,
|
|
107
|
+
credentials: {
|
|
108
|
+
user: updateSettings.username,
|
|
109
|
+
password: updateSettings.password,
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
expect(result).toEqual({
|
|
115
|
+
assigns: {
|
|
116
|
+
general_settings: {
|
|
117
|
+
...updateSettings,
|
|
118
|
+
id: revision.id,
|
|
119
|
+
originalId: revision.originalId,
|
|
120
|
+
},
|
|
121
|
+
errors: {
|
|
122
|
+
general_settings: { slug: "has invalid format" },
|
|
123
|
+
},
|
|
124
|
+
visibilityOptions: ctx.client.pages.visibilityOptions(),
|
|
125
|
+
_translations: [],
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("update when a revision does not exist", async () => {
|
|
131
|
+
const revision = Factory.build("page_revision");
|
|
132
|
+
|
|
133
|
+
const updateSettings = {};
|
|
134
|
+
|
|
135
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
136
|
+
|
|
137
|
+
const mockFind = jest
|
|
138
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
139
|
+
.mockImplementation(() => null);
|
|
140
|
+
|
|
141
|
+
expect(async () => {
|
|
142
|
+
await PageRevisionsGeneralHandler.update(ctx);
|
|
143
|
+
}).rejects.toThrow(`Missing revision #${revision.id}`);
|
|
144
|
+
|
|
145
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const create = async (ctx) => {
|
|
2
|
+
const { parent_id } = ctx.params;
|
|
3
|
+
|
|
4
|
+
const { errors, pageErrors } = await ctx.client.pageRevisions.create(
|
|
5
|
+
parent_id,
|
|
6
|
+
ctx.locale
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
if (errors) {
|
|
10
|
+
throw new Error(`Failed to start revision: ${JSON.stringify(errors)}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (pageErrors) {
|
|
14
|
+
throw new Error(`Failed to start revision: ${JSON.stringify(pageErrors)}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
redirect: `/${ctx.locale}/pages/${parent_id}`,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const destroy = async (ctx) => {
|
|
23
|
+
const { id } = ctx.params;
|
|
24
|
+
|
|
25
|
+
const { errors, revision } = await ctx.client.pageRevisions.delete(
|
|
26
|
+
id,
|
|
27
|
+
ctx.locale
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (errors) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to delete revision#${id}: ${JSON.stringify(errors)}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
headers: {
|
|
38
|
+
"HX-Redirect": `/${ctx.locale}/pages/${revision.originalId}`,
|
|
39
|
+
},
|
|
40
|
+
json: {},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
destroy,
|
|
46
|
+
create,
|
|
47
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import PageRevisionsHandler from "../PageRevisionsHandler";
|
|
2
|
+
import PageRevisions from "../../cloud/PageRevisions";
|
|
3
|
+
import { testConfig } from "../../../../../apps/admin/test/handlersHelper";
|
|
4
|
+
import Factory from "../../../../../apps/admin/test/factory";
|
|
5
|
+
|
|
6
|
+
function buildCtx(pageID) {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
pageRevisions: new PageRevisions(testConfig, "token"),
|
|
10
|
+
},
|
|
11
|
+
params: { parent_id: pageID },
|
|
12
|
+
locale: "en",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe("Page revisions", () => {
|
|
17
|
+
test("create successful", async () => {
|
|
18
|
+
const revision = Factory.build("page_revision", { originalId: 1 });
|
|
19
|
+
const ctx = buildCtx(revision.originalId);
|
|
20
|
+
|
|
21
|
+
const mockCreate = jest
|
|
22
|
+
.spyOn(ctx.client.pageRevisions, "create")
|
|
23
|
+
.mockImplementation(() => ({ revision, errors: null, pageErrors: null }));
|
|
24
|
+
|
|
25
|
+
const result = await PageRevisionsHandler.create(ctx);
|
|
26
|
+
|
|
27
|
+
expect(mockCreate).toHaveBeenCalledWith(revision.originalId, "en");
|
|
28
|
+
|
|
29
|
+
expect(result).toEqual({
|
|
30
|
+
redirect: `/en/pages/${revision.originalId}`,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("create failed with errors", async () => {
|
|
35
|
+
const ctx = buildCtx(1);
|
|
36
|
+
const errors = [{ key: "generalError", message: "something went wrong" }];
|
|
37
|
+
|
|
38
|
+
const mockCreate = jest
|
|
39
|
+
.spyOn(ctx.client.pageRevisions, "create")
|
|
40
|
+
.mockImplementation(() => ({ revision: null, errors, pageErrors: null }));
|
|
41
|
+
|
|
42
|
+
expect(async () => {
|
|
43
|
+
await PageRevisionsHandler.create(ctx);
|
|
44
|
+
}).rejects.toThrow(`Failed to start revision: ${JSON.stringify(errors)}`);
|
|
45
|
+
|
|
46
|
+
expect(mockCreate).toHaveBeenCalledWith(1, "en");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("create failed with page errors", async () => {
|
|
50
|
+
const ctx = buildCtx(1);
|
|
51
|
+
const errors = [{ key: "generalError", message: "something went wrong" }];
|
|
52
|
+
|
|
53
|
+
const mockCreate = jest
|
|
54
|
+
.spyOn(ctx.client.pageRevisions, "create")
|
|
55
|
+
.mockImplementation(() => ({
|
|
56
|
+
revision: null,
|
|
57
|
+
errors: null,
|
|
58
|
+
pageErrors: errors,
|
|
59
|
+
}));
|
|
60
|
+
|
|
61
|
+
expect(async () => {
|
|
62
|
+
await PageRevisionsHandler.create(ctx);
|
|
63
|
+
}).rejects.toThrow(`Failed to start revision: ${JSON.stringify(errors)}`);
|
|
64
|
+
|
|
65
|
+
expect(mockCreate).toHaveBeenCalledWith(1, "en");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import PageRevisionsHandler from "../PageRevisionsHandler";
|
|
2
|
+
import PageRevisions from "../../cloud/PageRevisions";
|
|
3
|
+
|
|
4
|
+
import { testConfig } from "../../../test/handlersHelper";
|
|
5
|
+
import Factory from "../../../test/factory";
|
|
6
|
+
|
|
7
|
+
function buildCtx(revisionID) {
|
|
8
|
+
return {
|
|
9
|
+
client: {
|
|
10
|
+
pageRevisions: new PageRevisions(testConfig, "token"),
|
|
11
|
+
},
|
|
12
|
+
params: { id: revisionID },
|
|
13
|
+
locale: "en",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("Page revisions", () => {
|
|
18
|
+
test("destroy successful", async () => {
|
|
19
|
+
const revision = Factory.build("page_revision");
|
|
20
|
+
const ctx = buildCtx(1);
|
|
21
|
+
|
|
22
|
+
const mockDelete = jest
|
|
23
|
+
.spyOn(ctx.client.pageRevisions, "delete")
|
|
24
|
+
.mockImplementation(() => ({ revision, errors: null }));
|
|
25
|
+
|
|
26
|
+
const result = await PageRevisionsHandler.destroy(ctx);
|
|
27
|
+
|
|
28
|
+
expect(mockDelete).toHaveBeenCalledWith(1, "en");
|
|
29
|
+
|
|
30
|
+
expect(result).toEqual({
|
|
31
|
+
headers: {
|
|
32
|
+
"HX-Redirect": `/en/pages/${revision.originalId}`,
|
|
33
|
+
},
|
|
34
|
+
json: {},
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("destroy failed", async () => {
|
|
39
|
+
const ctx = buildCtx(1);
|
|
40
|
+
const errors = [{ key: "generalError", message: "something went wrong" }];
|
|
41
|
+
|
|
42
|
+
const mockDelete = jest
|
|
43
|
+
.spyOn(ctx.client.pageRevisions, "delete")
|
|
44
|
+
.mockImplementation(() => ({ revision: null, errors }));
|
|
45
|
+
|
|
46
|
+
expect(async () => {
|
|
47
|
+
await PageRevisionsHandler.destroy(ctx);
|
|
48
|
+
}).rejects.toThrow(
|
|
49
|
+
`Failed to delete revision#${1}: ${JSON.stringify(errors)}`
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(mockDelete).toHaveBeenCalledWith(1, "en");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const create_form = async (ctx) => {
|
|
2
|
+
const { parent_id } = ctx.params;
|
|
3
|
+
|
|
4
|
+
const revision = await ctx.client.pageRevisions.find(parent_id, ctx.locale);
|
|
5
|
+
|
|
6
|
+
const lock_settings = {
|
|
7
|
+
revision,
|
|
8
|
+
message: "",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
assigns: {
|
|
13
|
+
lock_settings,
|
|
14
|
+
errors: {},
|
|
15
|
+
_translations: [],
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const create = async (ctx) => {
|
|
21
|
+
const { parent_id } = ctx.params;
|
|
22
|
+
const { message } = ctx.resourceParams.lock_settings;
|
|
23
|
+
|
|
24
|
+
const { revision, errors, pageErrors } = await ctx.client.pageRevisions.lock(
|
|
25
|
+
parent_id,
|
|
26
|
+
ctx.locale,
|
|
27
|
+
message
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (errors) {
|
|
31
|
+
return {
|
|
32
|
+
assigns: {
|
|
33
|
+
lock_settings: { revision, message },
|
|
34
|
+
errors: {
|
|
35
|
+
lock_settings: ctx.client.pages.formatErrors(errors, "message"),
|
|
36
|
+
},
|
|
37
|
+
_translations: [],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (pageErrors) {
|
|
43
|
+
throw `Failed to lock revisions: ${JSON.stringify(pageErrors)}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
redirect: `/${ctx.locale}/pages/${revision.originalId}`,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default {
|
|
52
|
+
create_form,
|
|
53
|
+
create,
|
|
54
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const edit_form = async (ctx) => {
|
|
2
|
+
const { parent_id } = ctx.params;
|
|
3
|
+
|
|
4
|
+
const revision = await ctx.client.pageRevisions.find(parent_id, ctx.locale);
|
|
5
|
+
|
|
6
|
+
if (!revision) {
|
|
7
|
+
throw new Error(`Missing revision #${parent_id}`);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const meta_settings = {
|
|
11
|
+
id: revision.id,
|
|
12
|
+
originalId: revision.originalId,
|
|
13
|
+
title: revision.settings.meta?.title || "",
|
|
14
|
+
description: revision.settings.meta?.description || "",
|
|
15
|
+
image: revision.settings.meta?.image || {},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
assigns: {
|
|
20
|
+
meta_settings,
|
|
21
|
+
errors: {},
|
|
22
|
+
_translations: [],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const update = async (ctx) => {
|
|
28
|
+
const { parent_id } = ctx.params;
|
|
29
|
+
|
|
30
|
+
const revision = await ctx.client.pageRevisions.find(parent_id, ctx.locale);
|
|
31
|
+
|
|
32
|
+
if (!revision) {
|
|
33
|
+
throw new Error(`Missing revision #${parent_id}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const params = ctx.resourceParams.meta_settings;
|
|
37
|
+
|
|
38
|
+
const { errors } = await ctx.client.pageRevisions.update(
|
|
39
|
+
revision.id,
|
|
40
|
+
ctx.locale,
|
|
41
|
+
{
|
|
42
|
+
slug: revision.slug,
|
|
43
|
+
title: revision.title,
|
|
44
|
+
visibility: revision.visibility,
|
|
45
|
+
widgets: JSON.stringify(revision.widgets),
|
|
46
|
+
tags: revision.tags.map((t) => t.id),
|
|
47
|
+
categories: revision.categories.map((c) => c.id),
|
|
48
|
+
settings: JSON.stringify({
|
|
49
|
+
...revision.settings,
|
|
50
|
+
meta: {
|
|
51
|
+
title: params.title,
|
|
52
|
+
description: params.description,
|
|
53
|
+
image: JSON.parse(params.image),
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (errors) {
|
|
60
|
+
return {
|
|
61
|
+
assigns: {
|
|
62
|
+
meta_settings: {
|
|
63
|
+
...params,
|
|
64
|
+
id: revision.id,
|
|
65
|
+
originalId: revision.originalId,
|
|
66
|
+
},
|
|
67
|
+
errors: {
|
|
68
|
+
meta_settings: ctx.client.pageRevisions.formatErrors(errors),
|
|
69
|
+
},
|
|
70
|
+
_translations: [],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
redirect: `/${ctx.locale}/page_revisions/${revision.id}/meta/edit`,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default {
|
|
81
|
+
edit_form,
|
|
82
|
+
update,
|
|
83
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import PageRevisionsMetaHandler from "../PageRevisionsMetaHandler";
|
|
2
|
+
import PageRevisions from "../../cloud/PageRevisions";
|
|
3
|
+
import { testConfig } from "../../../test/handlersHelper";
|
|
4
|
+
import Factory from "../../../test/factory";
|
|
5
|
+
|
|
6
|
+
function buildCtx(revision) {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
pageRevisions: new PageRevisions(testConfig, "token"),
|
|
10
|
+
},
|
|
11
|
+
params: { parent_id: revision.id },
|
|
12
|
+
locale: "en",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe("Page revision meta settings", () => {
|
|
17
|
+
test("edit_form when a revision exists", async () => {
|
|
18
|
+
const revision = Factory.build("page_revision");
|
|
19
|
+
const ctx = buildCtx(revision);
|
|
20
|
+
|
|
21
|
+
const mockFind = jest
|
|
22
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
23
|
+
.mockImplementation(() => revision);
|
|
24
|
+
|
|
25
|
+
const result = await PageRevisionsMetaHandler.edit_form(ctx);
|
|
26
|
+
|
|
27
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
28
|
+
|
|
29
|
+
expect(result).toEqual({
|
|
30
|
+
assigns: {
|
|
31
|
+
meta_settings: {
|
|
32
|
+
id: revision.id,
|
|
33
|
+
originalId: revision.originalId,
|
|
34
|
+
title: revision.settings.meta.title,
|
|
35
|
+
description: revision.settings.meta.description,
|
|
36
|
+
image: revision.settings.meta.image,
|
|
37
|
+
},
|
|
38
|
+
errors: {},
|
|
39
|
+
_translations: [],
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("edit_form when a revision does not exist", async () => {
|
|
45
|
+
const ctx = buildCtx({ id: "42" });
|
|
46
|
+
|
|
47
|
+
const mockFind = jest
|
|
48
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
49
|
+
.mockImplementation(() => null);
|
|
50
|
+
|
|
51
|
+
expect(async () => {
|
|
52
|
+
await PageRevisionsMetaHandler.edit_form(ctx);
|
|
53
|
+
}).rejects.toThrow("Missing revision #42");
|
|
54
|
+
|
|
55
|
+
expect(mockFind).toHaveBeenCalledWith("42", "en");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import PageRevisionsMetaHandler from "../PageRevisionsMetaHandler";
|
|
2
|
+
import PageRevisions from "../../cloud/PageRevisions";
|
|
3
|
+
import { testConfig } from "../../../../../apps/admin/test/handlersHelper";
|
|
4
|
+
import Factory from "../../../../../apps/admin/test/factory";
|
|
5
|
+
|
|
6
|
+
function buildCtx(revision, updateSettings) {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
pageRevisions: new PageRevisions(testConfig, "token"),
|
|
10
|
+
},
|
|
11
|
+
params: { parent_id: revision.id },
|
|
12
|
+
resourceParams: {
|
|
13
|
+
meta_settings: updateSettings,
|
|
14
|
+
},
|
|
15
|
+
locale: "en",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("Page revision meta settings", () => {
|
|
20
|
+
test("update successful", async () => {
|
|
21
|
+
const revision = Factory.build("page_revision");
|
|
22
|
+
|
|
23
|
+
const updateSettings = {
|
|
24
|
+
title: "An open graph title",
|
|
25
|
+
description: "An open graph description",
|
|
26
|
+
image: JSON.stringify({ id: 42 }),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
30
|
+
|
|
31
|
+
const mockFind = jest
|
|
32
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
33
|
+
.mockImplementation(() => revision);
|
|
34
|
+
|
|
35
|
+
const mockUpdate = jest
|
|
36
|
+
.spyOn(ctx.client.pageRevisions, "update")
|
|
37
|
+
.mockImplementation(() => ({
|
|
38
|
+
revision: {},
|
|
39
|
+
errors: null,
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
const result = await PageRevisionsMetaHandler.update(ctx);
|
|
43
|
+
|
|
44
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
45
|
+
expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", {
|
|
46
|
+
slug: revision.slug,
|
|
47
|
+
title: revision.title,
|
|
48
|
+
visibility: revision.visibility,
|
|
49
|
+
widgets: JSON.stringify(revision.widgets),
|
|
50
|
+
tags: revision.tags.map((t) => t.id),
|
|
51
|
+
categories: revision.categories.map((c) => c.id),
|
|
52
|
+
settings: JSON.stringify({
|
|
53
|
+
...revision.settings,
|
|
54
|
+
meta: {
|
|
55
|
+
title: updateSettings.title,
|
|
56
|
+
description: updateSettings.description,
|
|
57
|
+
image: { id: 42 },
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(result).toEqual({
|
|
63
|
+
redirect: `/en/page_revisions/${revision.id}/meta/edit`,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("update failed", async () => {
|
|
68
|
+
const revision = Factory.build("page_revision");
|
|
69
|
+
|
|
70
|
+
const updateSettings = {
|
|
71
|
+
title: "An open graph title",
|
|
72
|
+
description: "An open graph description",
|
|
73
|
+
image: JSON.stringify({ id: 42 }),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
77
|
+
|
|
78
|
+
const mockFind = jest
|
|
79
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
80
|
+
.mockImplementation(() => revision);
|
|
81
|
+
|
|
82
|
+
const mockUpdate = jest
|
|
83
|
+
.spyOn(ctx.client.pageRevisions, "update")
|
|
84
|
+
.mockImplementation(() => ({
|
|
85
|
+
revision: {},
|
|
86
|
+
errors: [{ key: "generalError", message: "some error" }],
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
const result = await PageRevisionsMetaHandler.update(ctx);
|
|
90
|
+
|
|
91
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
92
|
+
expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", {
|
|
93
|
+
slug: revision.slug,
|
|
94
|
+
title: revision.title,
|
|
95
|
+
visibility: revision.visibility,
|
|
96
|
+
widgets: JSON.stringify(revision.widgets),
|
|
97
|
+
tags: revision.tags.map((t) => t.id),
|
|
98
|
+
categories: revision.categories.map((c) => c.id),
|
|
99
|
+
settings: JSON.stringify({
|
|
100
|
+
...revision.settings,
|
|
101
|
+
meta: {
|
|
102
|
+
title: updateSettings.title,
|
|
103
|
+
description: updateSettings.description,
|
|
104
|
+
image: { id: 42 },
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(result).toEqual({
|
|
110
|
+
assigns: {
|
|
111
|
+
meta_settings: {
|
|
112
|
+
...updateSettings,
|
|
113
|
+
id: revision.id,
|
|
114
|
+
originalId: revision.originalId,
|
|
115
|
+
},
|
|
116
|
+
errors: {
|
|
117
|
+
meta_settings: { generalError: "some error" },
|
|
118
|
+
},
|
|
119
|
+
_translations: [],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("update when a revision does not exist", async () => {
|
|
125
|
+
const revision = Factory.build("page_revision");
|
|
126
|
+
|
|
127
|
+
const updateSettings = {};
|
|
128
|
+
|
|
129
|
+
const ctx = buildCtx(revision, updateSettings);
|
|
130
|
+
|
|
131
|
+
const mockFind = jest
|
|
132
|
+
.spyOn(ctx.client.pageRevisions, "find")
|
|
133
|
+
.mockImplementation(() => null);
|
|
134
|
+
|
|
135
|
+
expect(async () => {
|
|
136
|
+
await PageRevisionsMetaHandler.update(ctx);
|
|
137
|
+
}).rejects.toThrow(`Missing revision #${revision.id}`);
|
|
138
|
+
|
|
139
|
+
expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
|
|
140
|
+
});
|
|
141
|
+
});
|