@raketa-cloud/admin 0.0.88 → 0.0.90
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/jest.config.js +22 -0
- package/package.json +2 -2
- package/src/cloud/ArticleRevisions.js +33 -5
- package/src/cloud/Articles.js +34 -4
- package/src/cloud/EventRevisions.js +33 -5
- package/src/cloud/Events.js +35 -5
- package/src/cloud/PageRevisions.js +31 -3
- package/src/cloud/Pages.js +34 -4
- package/src/cloud/documents/articlesDocuments.js +44 -3
- package/src/cloud/documents/eventsDocuments.js +43 -2
- package/src/cloud/documents/pagesDocuments.js +43 -2
- package/src/handlers/articles/TranslationsHandler.js +81 -15
- package/src/handlers/events/TranslationsHandler.js +80 -14
- package/src/handlers/pages/TranslationsHandler.js +84 -18
- package/src/helpers/AuthHelper.js +2 -2
- package/src/tests/handlers/TagsHandler.test/create.test.js +96 -0
- package/src/tests/handlers/TagsHandler.test/create_form.test.js +25 -0
- package/src/tests/handlers/TagsHandler.test/destroy.test.js +51 -0
- package/src/tests/handlers/TagsHandler.test/edit_form.test.js +60 -0
- package/src/tests/handlers/TagsHandler.test/index.test.js +37 -0
- package/src/tests/handlers/TagsHandler.test/update.test.js +105 -0
- package/src/tests/handlers/articles/TranslationHandler.test/create.test.js +85 -79
- package/src/tests/handlers/events/TranslationHandler.test/create.test.js +84 -78
- package/src/tests/handlers/pages/TranslationHandler.test/create.test.js +83 -72
- package/src/tests/helpers/AuthHelper.test.js +169 -0
- package/src/tests/helpers/FormBuildert.test.js +357 -0
- package/src/tests/helpers/Inflector.test.js +75 -0
- package/src/views/articles/translations/create_form.ejs +2 -0
- package/src/views/events/translations/create_form.ejs +2 -0
- package/src/views/pages/translations/create_form.ejs +3 -1
|
@@ -76,7 +76,28 @@ const create_form = async (ctx) => {
|
|
|
76
76
|
const create = async (ctx) => {
|
|
77
77
|
const { parent_id } = ctx.params;
|
|
78
78
|
const originalLocale = ctx.locale;
|
|
79
|
-
const blueprint = await ctx.client.articles.find(parent_id,
|
|
79
|
+
const blueprint = await ctx.client.articles.find(parent_id, originalLocale);
|
|
80
|
+
|
|
81
|
+
if (!ctx.resourceParams?.resource?.languages) {
|
|
82
|
+
return {
|
|
83
|
+
assigns: {
|
|
84
|
+
resource: {
|
|
85
|
+
translations: blueprint.translations || {},
|
|
86
|
+
languages: [],
|
|
87
|
+
},
|
|
88
|
+
blueprint,
|
|
89
|
+
targetLocale: originalLocale,
|
|
90
|
+
errors: {
|
|
91
|
+
resource: ctx.client.articles.formatErrors([
|
|
92
|
+
{
|
|
93
|
+
key: "languages",
|
|
94
|
+
message: "select at least one language for translation",
|
|
95
|
+
},
|
|
96
|
+
]),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
80
101
|
|
|
81
102
|
const formLanguages = Array.isArray(ctx.resourceParams.resource.languages)
|
|
82
103
|
? ctx.resourceParams.resource.languages
|
|
@@ -98,18 +119,61 @@ const create = async (ctx) => {
|
|
|
98
119
|
tags: [],
|
|
99
120
|
};
|
|
100
121
|
|
|
122
|
+
const resource = ctx.client.articles.deepMerge(params, {
|
|
123
|
+
visibility: "private",
|
|
124
|
+
});
|
|
125
|
+
|
|
101
126
|
const translationIds = [];
|
|
102
127
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
128
|
+
const translations = await ctx.client.articles.translateBatch(
|
|
129
|
+
parent_id,
|
|
130
|
+
selectedLocales,
|
|
131
|
+
resource
|
|
132
|
+
);
|
|
107
133
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
if (!translations) {
|
|
135
|
+
return {
|
|
136
|
+
assigns: {
|
|
137
|
+
resource: {
|
|
138
|
+
...resource,
|
|
139
|
+
translations: blueprint.translations || {},
|
|
140
|
+
languages: formLanguages,
|
|
141
|
+
},
|
|
142
|
+
blueprint,
|
|
143
|
+
targetLocale: originalLocale,
|
|
144
|
+
errors: {
|
|
145
|
+
resource: ctx.client.articles.formatErrors([
|
|
146
|
+
{
|
|
147
|
+
key: "generalError",
|
|
148
|
+
message: "Failed to process translations",
|
|
149
|
+
},
|
|
150
|
+
]),
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < translations.length; i++) {
|
|
157
|
+
const { article } = translations[i];
|
|
158
|
+
const locale = selectedLocales[i];
|
|
159
|
+
|
|
160
|
+
if (article) {
|
|
161
|
+
blueprint.translations = {
|
|
162
|
+
...blueprint.translations,
|
|
163
|
+
[locale]: {
|
|
164
|
+
id: article.id,
|
|
165
|
+
slug: article.slug,
|
|
166
|
+
visibility: article.visibility,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const revisionInputs = [];
|
|
173
|
+
|
|
174
|
+
for (let i = 0; i < translations.length; i++) {
|
|
175
|
+
const { errors, article } = translations[i];
|
|
176
|
+
const locale = selectedLocales[i];
|
|
113
177
|
|
|
114
178
|
if (errors) {
|
|
115
179
|
return {
|
|
@@ -128,13 +192,15 @@ const create = async (ctx) => {
|
|
|
128
192
|
|
|
129
193
|
if (article) {
|
|
130
194
|
translationIds.push(`${locale}:${article.id}`);
|
|
195
|
+
revisionInputs.push({ articleId: article.id, locale });
|
|
131
196
|
}
|
|
197
|
+
}
|
|
132
198
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
locale
|
|
136
|
-
);
|
|
199
|
+
const revisionResults =
|
|
200
|
+
await ctx.client.articleRevisions.createBatch(revisionInputs);
|
|
137
201
|
|
|
202
|
+
for (let i = 0; i < revisionResults.length; i++) {
|
|
203
|
+
const { errors: revisionErrors } = revisionResults[i];
|
|
138
204
|
if (revisionErrors) {
|
|
139
205
|
return {
|
|
140
206
|
assigns: {
|
|
@@ -144,7 +210,7 @@ const create = async (ctx) => {
|
|
|
144
210
|
languages: formLanguages,
|
|
145
211
|
},
|
|
146
212
|
blueprint,
|
|
147
|
-
targetLocale:
|
|
213
|
+
targetLocale: selectedLocales[i],
|
|
148
214
|
errors: {
|
|
149
215
|
resource: ctx.client.articles.formatErrors(revisionErrors),
|
|
150
216
|
},
|
|
@@ -78,6 +78,27 @@ const create = async (ctx) => {
|
|
|
78
78
|
const originalLocale = ctx.locale;
|
|
79
79
|
const blueprint = await ctx.client.events.find(parent_id, ctx.locale);
|
|
80
80
|
|
|
81
|
+
if (!ctx.resourceParams?.resource?.languages) {
|
|
82
|
+
return {
|
|
83
|
+
assigns: {
|
|
84
|
+
resource: {
|
|
85
|
+
translations: blueprint.translations || {},
|
|
86
|
+
languages: [],
|
|
87
|
+
},
|
|
88
|
+
blueprint,
|
|
89
|
+
targetLocale: originalLocale,
|
|
90
|
+
errors: {
|
|
91
|
+
resource: ctx.client.events.formatErrors([
|
|
92
|
+
{
|
|
93
|
+
key: "languages",
|
|
94
|
+
message: "select at least one language for translation",
|
|
95
|
+
},
|
|
96
|
+
]),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
81
102
|
const formLanguages = Array.isArray(ctx.resourceParams.resource.languages)
|
|
82
103
|
? ctx.resourceParams.resource.languages
|
|
83
104
|
: [ctx.resourceParams.resource.languages].filter(Boolean);
|
|
@@ -100,18 +121,61 @@ const create = async (ctx) => {
|
|
|
100
121
|
tags: [],
|
|
101
122
|
};
|
|
102
123
|
|
|
124
|
+
const resource = ctx.client.events.deepMerge(params, {
|
|
125
|
+
visibility: "private",
|
|
126
|
+
});
|
|
127
|
+
|
|
103
128
|
const translationIds = [];
|
|
104
129
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
130
|
+
const translations = await ctx.client.events.translateBatch(
|
|
131
|
+
parent_id,
|
|
132
|
+
selectedLocales,
|
|
133
|
+
resource
|
|
134
|
+
);
|
|
109
135
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
if (!translations) {
|
|
137
|
+
return {
|
|
138
|
+
assigns: {
|
|
139
|
+
resource: {
|
|
140
|
+
...resource,
|
|
141
|
+
translations: blueprint.translations || {},
|
|
142
|
+
languages: formLanguages,
|
|
143
|
+
},
|
|
144
|
+
blueprint,
|
|
145
|
+
targetLocale: originalLocale,
|
|
146
|
+
errors: {
|
|
147
|
+
resource: ctx.client.events.formatErrors([
|
|
148
|
+
{
|
|
149
|
+
key: "generalError",
|
|
150
|
+
message: "Failed to process translations",
|
|
151
|
+
},
|
|
152
|
+
]),
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
for (let i = 0; i < translations.length; i++) {
|
|
159
|
+
const { event } = translations[i];
|
|
160
|
+
const locale = selectedLocales[i];
|
|
161
|
+
|
|
162
|
+
if (event) {
|
|
163
|
+
blueprint.translations = {
|
|
164
|
+
...blueprint.translations,
|
|
165
|
+
[locale]: {
|
|
166
|
+
id: event.id,
|
|
167
|
+
slug: event.slug,
|
|
168
|
+
visibility: event.visibility,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const revisionInputs = [];
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < translations.length; i++) {
|
|
177
|
+
const { errors, event } = translations[i];
|
|
178
|
+
const locale = selectedLocales[i];
|
|
115
179
|
|
|
116
180
|
if (errors) {
|
|
117
181
|
return {
|
|
@@ -130,13 +194,15 @@ const create = async (ctx) => {
|
|
|
130
194
|
|
|
131
195
|
if (event) {
|
|
132
196
|
translationIds.push(`${locale}:${event.id}`);
|
|
197
|
+
revisionInputs.push({ eventId: event.id, locale });
|
|
133
198
|
}
|
|
199
|
+
}
|
|
134
200
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
locale
|
|
138
|
-
);
|
|
201
|
+
const revisionResults =
|
|
202
|
+
await ctx.client.eventRevisions.createBatch(revisionInputs);
|
|
139
203
|
|
|
204
|
+
for (let i = 0; i < revisionResults.length; i++) {
|
|
205
|
+
const { errors: revisionErrors } = revisionResults[i];
|
|
140
206
|
if (revisionErrors) {
|
|
141
207
|
return {
|
|
142
208
|
assigns: {
|
|
@@ -146,7 +212,7 @@ const create = async (ctx) => {
|
|
|
146
212
|
languages: formLanguages,
|
|
147
213
|
},
|
|
148
214
|
blueprint,
|
|
149
|
-
targetLocale:
|
|
215
|
+
targetLocale: selectedLocales[i],
|
|
150
216
|
errors: {
|
|
151
217
|
resource: ctx.client.events.formatErrors(revisionErrors),
|
|
152
218
|
},
|
|
@@ -78,6 +78,27 @@ const create = async (ctx) => {
|
|
|
78
78
|
const originalLocale = ctx.locale;
|
|
79
79
|
const blueprint = await ctx.client.pages.find(parent_id, originalLocale);
|
|
80
80
|
|
|
81
|
+
if (!ctx.resourceParams?.resource?.languages) {
|
|
82
|
+
return {
|
|
83
|
+
assigns: {
|
|
84
|
+
resource: {
|
|
85
|
+
translations: blueprint.translations || {},
|
|
86
|
+
languages: [],
|
|
87
|
+
},
|
|
88
|
+
blueprint,
|
|
89
|
+
targetLocale: originalLocale,
|
|
90
|
+
errors: {
|
|
91
|
+
resource: ctx.client.pages.formatErrors([
|
|
92
|
+
{
|
|
93
|
+
key: "languages",
|
|
94
|
+
message: "select at least one language for translation",
|
|
95
|
+
},
|
|
96
|
+
]),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
81
102
|
const formLanguages = Array.isArray(ctx.resourceParams.resource.languages)
|
|
82
103
|
? ctx.resourceParams.resource.languages
|
|
83
104
|
: [ctx.resourceParams.resource.languages].filter(Boolean);
|
|
@@ -95,23 +116,66 @@ const create = async (ctx) => {
|
|
|
95
116
|
slug: blueprint.slug,
|
|
96
117
|
};
|
|
97
118
|
|
|
119
|
+
const resource = ctx.client.pages.deepMerge(
|
|
120
|
+
{
|
|
121
|
+
settings: blueprint.settings,
|
|
122
|
+
widgets: blueprint.widgets,
|
|
123
|
+
categories: blueprint.categories.map((category) => category.id),
|
|
124
|
+
},
|
|
125
|
+
params
|
|
126
|
+
);
|
|
127
|
+
|
|
98
128
|
const translationIds = [];
|
|
99
129
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
130
|
+
const translations = await ctx.client.pages.translateBatch(
|
|
131
|
+
parent_id,
|
|
132
|
+
selectedLocales,
|
|
133
|
+
resource
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (!translations) {
|
|
137
|
+
return {
|
|
138
|
+
assigns: {
|
|
139
|
+
resource: {
|
|
140
|
+
...resource,
|
|
141
|
+
translations: blueprint.translations || {},
|
|
142
|
+
languages: formLanguages,
|
|
143
|
+
},
|
|
144
|
+
blueprint,
|
|
145
|
+
targetLocale: originalLocale,
|
|
146
|
+
errors: {
|
|
147
|
+
resource: ctx.client.pages.formatErrors([
|
|
148
|
+
{
|
|
149
|
+
key: "generalError",
|
|
150
|
+
message: "Failed to process translations",
|
|
151
|
+
},
|
|
152
|
+
]),
|
|
153
|
+
},
|
|
106
154
|
},
|
|
107
|
-
|
|
108
|
-
|
|
155
|
+
};
|
|
156
|
+
}
|
|
109
157
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
158
|
+
for (let i = 0; i < translations.length; i++) {
|
|
159
|
+
const { page } = translations[i];
|
|
160
|
+
const locale = selectedLocales[i];
|
|
161
|
+
|
|
162
|
+
if (page) {
|
|
163
|
+
blueprint.translations = {
|
|
164
|
+
...blueprint.translations,
|
|
165
|
+
[locale]: {
|
|
166
|
+
id: page.id,
|
|
167
|
+
slug: page.slug,
|
|
168
|
+
visibility: page.visibility,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const revisionInputs = [];
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < translations.length; i++) {
|
|
177
|
+
const { errors, page } = translations[i];
|
|
178
|
+
const locale = selectedLocales[i];
|
|
115
179
|
|
|
116
180
|
if (errors) {
|
|
117
181
|
return {
|
|
@@ -130,13 +194,15 @@ const create = async (ctx) => {
|
|
|
130
194
|
|
|
131
195
|
if (page) {
|
|
132
196
|
translationIds.push(`${locale}:${page.id}`);
|
|
197
|
+
revisionInputs.push({ pageId: page.id, locale });
|
|
133
198
|
}
|
|
199
|
+
}
|
|
134
200
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
locale
|
|
138
|
-
);
|
|
201
|
+
const revisionResults =
|
|
202
|
+
await ctx.client.pageRevisions.createBatch(revisionInputs);
|
|
139
203
|
|
|
204
|
+
for (let i = 0; i < revisionResults.length; i++) {
|
|
205
|
+
const { errors: revisionErrors } = revisionResults[i];
|
|
140
206
|
if (revisionErrors) {
|
|
141
207
|
return {
|
|
142
208
|
assigns: {
|
|
@@ -146,7 +212,7 @@ const create = async (ctx) => {
|
|
|
146
212
|
languages: formLanguages,
|
|
147
213
|
},
|
|
148
214
|
blueprint,
|
|
149
|
-
targetLocale:
|
|
215
|
+
targetLocale: selectedLocales[i],
|
|
150
216
|
errors: {
|
|
151
217
|
resource: ctx.client.pages.formatErrors(revisionErrors),
|
|
152
218
|
},
|
|
@@ -33,12 +33,12 @@ const AuthHelper = {
|
|
|
33
33
|
auth_callback_url,
|
|
34
34
|
}) => {
|
|
35
35
|
if (
|
|
36
|
-
[
|
|
36
|
+
![
|
|
37
37
|
gateway_url,
|
|
38
38
|
gateway_project,
|
|
39
39
|
gateway_user_pool,
|
|
40
40
|
auth_callback_url,
|
|
41
|
-
].
|
|
41
|
+
].every(Boolean)
|
|
42
42
|
)
|
|
43
43
|
throw new Error("Invalid ENVs for authentication configuration");
|
|
44
44
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import Tags from "../../../cloud/Tags";
|
|
2
|
+
import TagsHandler from "../../../handlers/TagsHandler";
|
|
3
|
+
import Factory from "../../support/factory";
|
|
4
|
+
|
|
5
|
+
describe("Tags Handler", () => {
|
|
6
|
+
function buildCtx(tag) {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
tags: new Tags(() => ({}), "token"),
|
|
10
|
+
},
|
|
11
|
+
resourceParams: {
|
|
12
|
+
tag: {
|
|
13
|
+
name: tag.name,
|
|
14
|
+
slug: tag.slug,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
locale: "en",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test("create successful", async () => {
|
|
22
|
+
const tag = Factory.build("tag", {
|
|
23
|
+
name: "Test Tag",
|
|
24
|
+
slug: "test-tag",
|
|
25
|
+
});
|
|
26
|
+
const ctx = buildCtx(tag);
|
|
27
|
+
|
|
28
|
+
const mockedCreate = jest
|
|
29
|
+
.spyOn(ctx.client.tags, "create")
|
|
30
|
+
.mockImplementation(() => ({ tag, errors: null }));
|
|
31
|
+
|
|
32
|
+
const result = await TagsHandler.create(ctx);
|
|
33
|
+
|
|
34
|
+
expect(mockedCreate).toHaveBeenCalledWith(
|
|
35
|
+
{
|
|
36
|
+
name: tag.name,
|
|
37
|
+
slug: tag.slug,
|
|
38
|
+
},
|
|
39
|
+
"en"
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
expect(result).toEqual({
|
|
43
|
+
redirect: "/en/tags",
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("create failed", async () => {
|
|
48
|
+
const tag = Factory.build("tag", {
|
|
49
|
+
name: "Test Tag",
|
|
50
|
+
slug: "test-tag",
|
|
51
|
+
});
|
|
52
|
+
const ctx = buildCtx(tag);
|
|
53
|
+
|
|
54
|
+
const errors = [{ key: "name", message: "already taken" }];
|
|
55
|
+
|
|
56
|
+
const mockedCreate = jest
|
|
57
|
+
.spyOn(ctx.client.tags, "create")
|
|
58
|
+
.mockImplementation(() => ({
|
|
59
|
+
tag: null,
|
|
60
|
+
errors,
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
const mockedFormatErrors = jest
|
|
64
|
+
.spyOn(ctx.client.tags, "formatErrors")
|
|
65
|
+
.mockImplementation(() => ({
|
|
66
|
+
name: "already taken",
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
const result = await TagsHandler.create(ctx);
|
|
70
|
+
|
|
71
|
+
expect(mockedCreate).toHaveBeenCalledWith(
|
|
72
|
+
{
|
|
73
|
+
name: tag.name,
|
|
74
|
+
slug: tag.slug,
|
|
75
|
+
},
|
|
76
|
+
"en"
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
expect(mockedFormatErrors).toHaveBeenCalledWith(errors);
|
|
80
|
+
|
|
81
|
+
expect(result).toEqual({
|
|
82
|
+
assigns: {
|
|
83
|
+
tag: {
|
|
84
|
+
name: tag.name,
|
|
85
|
+
slug: tag.slug,
|
|
86
|
+
},
|
|
87
|
+
errors: {
|
|
88
|
+
tag: {
|
|
89
|
+
name: "already taken",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
_translations: [],
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Tags from "../../../cloud/Tags";
|
|
2
|
+
import TagsHandler from "../../../handlers/TagsHandler";
|
|
3
|
+
|
|
4
|
+
describe("Tags Handler", () => {
|
|
5
|
+
function buildCtx() {
|
|
6
|
+
return {
|
|
7
|
+
client: {
|
|
8
|
+
tags: new Tags(() => ({}), "token"),
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test("create_form", () => {
|
|
14
|
+
const ctx = buildCtx();
|
|
15
|
+
const result = TagsHandler.create_form(ctx);
|
|
16
|
+
|
|
17
|
+
expect(result).toEqual({
|
|
18
|
+
assigns: {
|
|
19
|
+
tag: {},
|
|
20
|
+
errors: {},
|
|
21
|
+
_translations: [],
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import Tags from "../../../cloud/Tags";
|
|
2
|
+
import TagsHandler from "../../../handlers/TagsHandler";
|
|
3
|
+
import Factory from "../../support/factory";
|
|
4
|
+
|
|
5
|
+
describe("Tags Handler", () => {
|
|
6
|
+
function buildCtx() {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
tags: new Tags(() => ({}), "token"),
|
|
10
|
+
},
|
|
11
|
+
params: { id: "1" },
|
|
12
|
+
locale: "en",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test("destroy successful", async () => {
|
|
17
|
+
const tag = Factory.build("tag");
|
|
18
|
+
const ctx = buildCtx();
|
|
19
|
+
|
|
20
|
+
const mockedDelete = jest
|
|
21
|
+
.spyOn(ctx.client.tags, "delete")
|
|
22
|
+
.mockImplementation(() => ({ tag, errors: null }));
|
|
23
|
+
|
|
24
|
+
const result = await TagsHandler.destroy(ctx);
|
|
25
|
+
|
|
26
|
+
expect(mockedDelete).toHaveBeenCalledWith("1", "en");
|
|
27
|
+
expect(result).toEqual({
|
|
28
|
+
headers: {
|
|
29
|
+
"HX-redirect": "/en/tags",
|
|
30
|
+
},
|
|
31
|
+
json: {},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("destroy failed", async () => {
|
|
36
|
+
const ctx = buildCtx();
|
|
37
|
+
|
|
38
|
+
const mockedDelete = jest
|
|
39
|
+
.spyOn(ctx.client.tags, "delete")
|
|
40
|
+
.mockImplementation(() => ({
|
|
41
|
+
tag: null,
|
|
42
|
+
errors: [{ key: "generalError", message: "Not found" }],
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
expect(() => TagsHandler.destroy(ctx)).rejects.toMatch(
|
|
46
|
+
"Failed to delete tag #1. WTF?"
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(mockedDelete).toHaveBeenCalledWith("1", "en");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import Tags from "../../../cloud/Tags";
|
|
2
|
+
import TagsHandler from "../../../handlers/TagsHandler";
|
|
3
|
+
import Factory from "../../support/factory";
|
|
4
|
+
|
|
5
|
+
describe("Tags Handler", () => {
|
|
6
|
+
function buildCtx() {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
tags: new Tags(() => ({}), "token"),
|
|
10
|
+
},
|
|
11
|
+
router: {
|
|
12
|
+
req: {
|
|
13
|
+
param: () => ({ id: "1" }),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
locale: "en",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("edit_form", async () => {
|
|
21
|
+
const tag = Factory.build("tag", { id: "1", name: "Test Tag" });
|
|
22
|
+
const ctx = buildCtx();
|
|
23
|
+
|
|
24
|
+
const mockedFind = jest
|
|
25
|
+
.spyOn(ctx.client.tags, "find")
|
|
26
|
+
.mockImplementation(() => tag);
|
|
27
|
+
|
|
28
|
+
const result = await TagsHandler.edit_form(ctx);
|
|
29
|
+
|
|
30
|
+
expect(mockedFind).toHaveBeenCalledWith("1", "en");
|
|
31
|
+
expect(result).toEqual({
|
|
32
|
+
assigns: {
|
|
33
|
+
id: "1",
|
|
34
|
+
tag: tag,
|
|
35
|
+
errors: {},
|
|
36
|
+
_translations: [],
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("edit_form when tag does not exist", async () => {
|
|
42
|
+
const ctx = buildCtx();
|
|
43
|
+
|
|
44
|
+
const mockedFind = jest
|
|
45
|
+
.spyOn(ctx.client.tags, "find")
|
|
46
|
+
.mockImplementation(() => null);
|
|
47
|
+
|
|
48
|
+
const result = await TagsHandler.edit_form(ctx);
|
|
49
|
+
|
|
50
|
+
expect(mockedFind).toHaveBeenCalledWith("1", "en");
|
|
51
|
+
expect(result).toEqual({
|
|
52
|
+
assigns: {
|
|
53
|
+
id: "1",
|
|
54
|
+
tag: null,
|
|
55
|
+
errors: {},
|
|
56
|
+
_translations: [],
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Tags from "../../../cloud/Tags";
|
|
2
|
+
import TagsHandler from "../../../handlers/TagsHandler";
|
|
3
|
+
import Factory from "../../support/factory";
|
|
4
|
+
|
|
5
|
+
describe("Tags Handler", () => {
|
|
6
|
+
function buildCtx() {
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
tags: new Tags(() => ({}), "token"),
|
|
10
|
+
},
|
|
11
|
+
query: { foo: "bar" },
|
|
12
|
+
locale: "en",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test("index", async () => {
|
|
17
|
+
const tags = [
|
|
18
|
+
Factory.build("tag", { id: "1", name: "First Tag" }),
|
|
19
|
+
Factory.build("tag", { id: "2", name: "Second Tag" }),
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const ctx = buildCtx();
|
|
23
|
+
|
|
24
|
+
const mockedList = jest
|
|
25
|
+
.spyOn(ctx.client.tags, "list")
|
|
26
|
+
.mockImplementation(() => tags);
|
|
27
|
+
|
|
28
|
+
const result = await TagsHandler.index(ctx);
|
|
29
|
+
|
|
30
|
+
expect(mockedList).toHaveBeenCalledWith({ foo: "bar" }, "en");
|
|
31
|
+
expect(result).toEqual({
|
|
32
|
+
assigns: {
|
|
33
|
+
items: tags,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|