@opengis/cms 0.0.1
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/.gitlab-ci.yml +36 -0
- package/README.md +5 -0
- package/config.example +21 -0
- package/docs/.vitepress/abbr.mjs +26 -0
- package/docs/.vitepress/config.mjs +119 -0
- package/docs/.vitepress/navigation.mjs +82 -0
- package/docs/.vitepress/theme/Layout.vue +17 -0
- package/docs/.vitepress/theme/components/NavigationLinks.vue +102 -0
- package/docs/.vitepress/theme/components/Panzoom.vue +169 -0
- package/docs/.vitepress/theme/index.mjs +15 -0
- package/docs/.vitepress/theme/style.scss +136 -0
- package/docs/abbr.json +4 -0
- package/docs/api/builder/cms.builder.delete.md +65 -0
- package/docs/api/builder/cms.builder.get.md +70 -0
- package/docs/api/builder/cms.builder.list.md +98 -0
- package/docs/api/builder/cms.builder.post.md +72 -0
- package/docs/api/builder/cms.builder.put.md +88 -0
- package/docs/api/category/cms.category.delete.md +60 -0
- package/docs/api/category/cms.category.get.md +61 -0
- package/docs/api/category/cms.category.list.md +77 -0
- package/docs/api/category/cms.category.post.md +62 -0
- package/docs/api/category/cms.category.put.md +78 -0
- package/docs/api/index.md +50 -0
- package/docs/api/manager/cms.manager.delete.md +64 -0
- package/docs/api/manager/cms.manager.get.md +72 -0
- package/docs/api/manager/cms.manager.list.md +96 -0
- package/docs/api/manager/cms.manager.post.md +70 -0
- package/docs/api/manager/cms.manager.put.md +86 -0
- package/docs/api/media/del.md +64 -0
- package/docs/api/media/edit.md +92 -0
- package/docs/api/media/list.md +70 -0
- package/docs/api/media/metadata.md +57 -0
- package/docs/api/media/preview.md +33 -0
- package/docs/api/media/upload.md +84 -0
- package/docs/db/erd.md +173 -0
- package/docs/db/index.md +7 -0
- package/docs/index.md +39 -0
- package/docs/public/logo-dark.svg +24 -0
- package/docs/public/logo-light.svg +24 -0
- package/docs/public/logo-short.svg +15 -0
- package/docs/public/logo.svg +19 -0
- package/docs/readme/index.md +6 -0
- package/docs/src/vs-button.vue +157 -0
- package/docs/vue/basic/button.md +144 -0
- package/docs/vue/index.md +9 -0
- package/editor/index.html +14 -0
- package/editor/public/vite.svg +1 -0
- package/editor/src/App.vue +4 -0
- package/editor/src/assets/tailwind/tailwind.js +62 -0
- package/editor/src/assets/vue.svg +1 -0
- package/editor/src/components/builder/vs-builder-content.vue +163 -0
- package/editor/src/components/builder/vs-builder-menu.vue +142 -0
- package/editor/src/components/formats/index.js +8 -0
- package/editor/src/components/formats/vs-manager-table-date.vue +29 -0
- package/editor/src/components/formats/vs-manager-table-switch.vue +16 -0
- package/editor/src/components/icons/icon-actions.vue +24 -0
- package/editor/src/components/icons/icon-arrow-left.vue +19 -0
- package/editor/src/components/icons/icon-check.vue +23 -0
- package/editor/src/components/icons/icon-chewron-right.vue +16 -0
- package/editor/src/components/icons/icon-close.vue +22 -0
- package/editor/src/components/icons/icon-edit.vue +22 -0
- package/editor/src/components/icons/icon-folder.vue +18 -0
- package/editor/src/components/icons/icon-folder2.vue +17 -0
- package/editor/src/components/icons/icon-home.vue +16 -0
- package/editor/src/components/icons/icon-image.vue +18 -0
- package/editor/src/components/icons/icon-logo.vue +22 -0
- package/editor/src/components/icons/icon-media.vue +22 -0
- package/editor/src/components/icons/icon-point.vue +11 -0
- package/editor/src/components/icons/icon-search.vue +22 -0
- package/editor/src/components/icons/icon-table.vue +22 -0
- package/editor/src/components/icons/icon-users.vue +18 -0
- package/editor/src/components/icons/icon.plus.vue +18 -0
- package/editor/src/components/manager/children/vs-manager-collection-content.vue +55 -0
- package/editor/src/components/manager/children/vs-manager-collection-item-content.vue +116 -0
- package/editor/src/components/manager/children/vs-manager-single-content.vue +112 -0
- package/editor/src/components/manager/manager-table/vs-manager-colection-table-add.vue +84 -0
- package/editor/src/components/manager/manager-table/vs-manager-collection-table.vue +59 -0
- package/editor/src/components/manager/vs-manager-menu.vue +73 -0
- package/editor/src/components/media/Breadcrumb.vue +73 -0
- package/editor/src/components/shared-components/vs-not-data.vue +213 -0
- package/editor/src/components/vs-main-menu.vue +53 -0
- package/editor/src/helpers/debounce.js +10 -0
- package/editor/src/helpers/translite.js +19 -0
- package/editor/src/main.js +30 -0
- package/editor/src/misc/import-file.js +32 -0
- package/editor/src/pages/vs-builder.vue +22 -0
- package/editor/src/pages/vs-layout.vue +17 -0
- package/editor/src/pages/vs-manager.vue +30 -0
- package/editor/src/pages/vs-media.vue +398 -0
- package/editor/src/router/router.js +9 -0
- package/editor/src/router/routes.config.js +40 -0
- package/editor/src/style.css +0 -0
- package/editor/src/templates/form-columns.js +70 -0
- package/editor/src/templates/form-template.js +22 -0
- package/editor/vite.config.js +37 -0
- package/package.json +48 -0
- package/server/app.js +25 -0
- package/server/config.js +5 -0
- package/server/index.js +23 -0
- package/server/migrations/media.sql +30 -0
- package/server/plugins/hook.js +91 -0
- package/server/plugins/vite.js +80 -0
- package/server/routes/builder/controllers/cms.builder.delete.js +21 -0
- package/server/routes/builder/controllers/cms.builder.get.js +17 -0
- package/server/routes/builder/controllers/cms.builder.list.js +16 -0
- package/server/routes/builder/controllers/cms.builder.post.js +21 -0
- package/server/routes/builder/controllers/cms.builder.put.js +23 -0
- package/server/routes/builder/index.mjs +22 -0
- package/server/routes/category/controllers/cms.category.delete.js +21 -0
- package/server/routes/category/controllers/cms.category.get.js +17 -0
- package/server/routes/category/controllers/cms.category.list.js +16 -0
- package/server/routes/category/controllers/cms.category.post.js +21 -0
- package/server/routes/category/controllers/cms.category.put.js +23 -0
- package/server/routes/category/index.mjs +22 -0
- package/server/routes/manager/controllers/cms.manager.delete.js +22 -0
- package/server/routes/manager/controllers/cms.manager.get.js +21 -0
- package/server/routes/manager/controllers/cms.manager.list.js +31 -0
- package/server/routes/manager/controllers/cms.manager.post.js +28 -0
- package/server/routes/manager/controllers/cms.manager.put.js +23 -0
- package/server/routes/manager/index.mjs +22 -0
- package/server/routes/media/controllers/delete.js +59 -0
- package/server/routes/media/controllers/edit.js +94 -0
- package/server/routes/media/controllers/list.js +74 -0
- package/server/routes/media/controllers/metadata.js +51 -0
- package/server/routes/media/controllers/preview.js +47 -0
- package/server/routes/media/controllers/upload.js +79 -0
- package/server/routes/media/index.mjs +16 -0
- package/server/routes/root.mjs +15 -0
- package/server/templates/cls/cms.category_type.json +10 -0
- package/server/templates/cls/cms.content_review_status.json +10 -0
- package/server/templates/cls/cms.content_status.json +10 -0
- package/server/templates/cls/cms.content_type.json +10 -0
- package/server/templates/cls/cms.lang.json +10 -0
- package/server/templates/page/login.html +59 -0
- package/server/templates/select/cms.category_id.sql +1 -0
- package/server/templates/select/cms.type_id.sql +1 -0
- package/test/config.js +17 -0
- package/test/files/eye.svg +4 -0
- package/test/helper.js +30 -0
- package/test/routes/builder.test.js +99 -0
- package/test/routes/category.test.js +97 -0
- package/test/routes/manager.test.js +103 -0
- package/test/routes/media.test.js +252 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
|
|
4
|
+
import { config, pgClients } from '@opengis/fastify-table/utils.js';
|
|
5
|
+
import build from '../helper.js';
|
|
6
|
+
|
|
7
|
+
test('cms category api', async (t) => {
|
|
8
|
+
const app = await build(t);
|
|
9
|
+
|
|
10
|
+
const pg = pgClients.client;
|
|
11
|
+
|
|
12
|
+
const prefix = config.prefix || '/api';
|
|
13
|
+
|
|
14
|
+
const testCategoryId = 'testCategory';
|
|
15
|
+
|
|
16
|
+
app.addHook('onRequest', async (req) => {
|
|
17
|
+
req.session = { passport: { user: { user_type: 'admin', uid: '1' } } };
|
|
18
|
+
req.user = req.session.passport.user;
|
|
19
|
+
req.uid = req.user.uid;
|
|
20
|
+
req.unittest = 1;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
await t.test('POST /cms-category', async () => {
|
|
24
|
+
const res = await app.inject({
|
|
25
|
+
method: 'POST',
|
|
26
|
+
url: `${prefix}/cms-category`,
|
|
27
|
+
body: {
|
|
28
|
+
category_id: testCategoryId,
|
|
29
|
+
title: 'Created value'
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
assert.equal(res.statusCode, 200);
|
|
33
|
+
const rep = res.json();
|
|
34
|
+
// console.log(rep);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await t.test('PUT /cms-category', async () => {
|
|
38
|
+
// await pg.query('insert into site.content_types (category_id, uid) values ($1, $2)', [testCategoryId, testUid]);
|
|
39
|
+
const res = await app.inject({
|
|
40
|
+
method: 'PUT',
|
|
41
|
+
url: `${prefix}/cms-category/${testCategoryId}`,
|
|
42
|
+
body: {
|
|
43
|
+
title: 'Edited value'
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
assert.equal(res.statusCode, 200);
|
|
47
|
+
const rep = res.json();
|
|
48
|
+
// console.log(rep);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await t.test('GET /cms-category/:id', async () => {
|
|
52
|
+
// await pg.query('insert into site.contents (content_id, uid) values ($1, $2)', [testContentId, testUid]);
|
|
53
|
+
const res = await app.inject({
|
|
54
|
+
method: 'GET',
|
|
55
|
+
url: `${prefix}/cms-category/${testCategoryId}`,
|
|
56
|
+
});
|
|
57
|
+
assert.equal(res.statusCode, 200);
|
|
58
|
+
const rep = res.json();
|
|
59
|
+
// console.log(rep);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await t.test('GET /cms-category', async () => {
|
|
63
|
+
// await pg.query('insert into site.contents (content_id, uid) values ($1, $2)', [testContentId, testUid]);
|
|
64
|
+
const res = await app.inject({
|
|
65
|
+
method: 'GET',
|
|
66
|
+
url: `${prefix}/cms-category`,
|
|
67
|
+
});
|
|
68
|
+
assert.equal(res.statusCode, 200);
|
|
69
|
+
const rep = res.json();
|
|
70
|
+
// console.log(rep);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await t.test('GET /cms-category?id', async () => {
|
|
74
|
+
// await pg.query('insert into site.contents (content_id, uid) values ($1, $2)', [testContentId, testUid]);
|
|
75
|
+
const res = await app.inject({
|
|
76
|
+
method: 'GET',
|
|
77
|
+
url: `${prefix}/cms-category?category_id=${testCategoryId}`,
|
|
78
|
+
});
|
|
79
|
+
assert.equal(res.statusCode, 200);
|
|
80
|
+
const rep = res.json();
|
|
81
|
+
// console.log(rep);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
await t.test('DELETE /cms-category/:id', async () => {
|
|
85
|
+
const res = await app.inject({
|
|
86
|
+
method: 'DELETE',
|
|
87
|
+
url: `${prefix}/cms-category/${testCategoryId}`,
|
|
88
|
+
});
|
|
89
|
+
assert.equal(res.statusCode, 200);
|
|
90
|
+
const rep = res.json();
|
|
91
|
+
// console.log(rep);
|
|
92
|
+
});
|
|
93
|
+
await t.test('clean up', async () => {
|
|
94
|
+
const { rowCount: categoryCount } = await pg.query('delete from site.categories where category_id=$1', [testCategoryId]);
|
|
95
|
+
console.log('clean up', categoryCount);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
|
|
4
|
+
import { config, pgClients, getMeta } from '@opengis/fastify-table/utils.js';
|
|
5
|
+
import build from '../helper.js';
|
|
6
|
+
|
|
7
|
+
test('cms manager api', async (t) => {
|
|
8
|
+
const app = await build(t);
|
|
9
|
+
|
|
10
|
+
const pg = pgClients.client;
|
|
11
|
+
|
|
12
|
+
const prefix = config.prefix || '/api';
|
|
13
|
+
|
|
14
|
+
const testContentId = 'testContent';
|
|
15
|
+
const testTypeId = 'testContent';
|
|
16
|
+
const testCategoryId = 'testContent';
|
|
17
|
+
const testTemplate = 'testContent';
|
|
18
|
+
const testUid = '1';
|
|
19
|
+
|
|
20
|
+
app.addHook('onRequest', async (req) => {
|
|
21
|
+
req.session = { passport: { user: { user_type: 'admin', uid: '1' } } };
|
|
22
|
+
req.user = req.session.passport.user;
|
|
23
|
+
req.unittest = 1;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
await t.test('POST /cms-manager/:template', async () => {
|
|
27
|
+
const res = await app.inject({
|
|
28
|
+
method: 'POST',
|
|
29
|
+
url: `${prefix}/cms-manager/news`,
|
|
30
|
+
body: {
|
|
31
|
+
content_id: testContentId,
|
|
32
|
+
title: 'Created value',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
assert.equal(res.statusCode, 200);
|
|
36
|
+
const rep = res.json();
|
|
37
|
+
// console.log(rep);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await t.test('GET /cms-manager/:template', async () => {
|
|
41
|
+
const res = await app.inject({
|
|
42
|
+
method: 'GET',
|
|
43
|
+
url: `${prefix}/cms-manager/news`,
|
|
44
|
+
});
|
|
45
|
+
assert.equal(res.statusCode, 200);
|
|
46
|
+
const rep = res.json();
|
|
47
|
+
|
|
48
|
+
const contentColumns = await getMeta({ table: 'site.contents' }).then(el => el.columns?.filter?.(el => !['cdate', 'editor_date', 'uid', 'editor_date'].includes(el.name))?.length || 0);
|
|
49
|
+
const customColumns = await pg.query(`select jsonb_array_length(columns::jsonb) from site.content_types where template=$1`, ['news']).then(el => el.rows?.[0]?.jsonb_array_length || 0);
|
|
50
|
+
assert.equal(rep.columns?.length, contentColumns + customColumns, res.body);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await t.test('PUT /cms-manager', async () => {
|
|
54
|
+
const res = await app.inject({
|
|
55
|
+
method: 'PUT',
|
|
56
|
+
url: `${prefix}/cms-manager/${testContentId}`,
|
|
57
|
+
body: {
|
|
58
|
+
title: 'Edited value'
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
assert.equal(res.statusCode, 200);
|
|
62
|
+
const rep = res.json();
|
|
63
|
+
// console.log(rep);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await t.test('GET /cms-manager/:type', async () => {
|
|
67
|
+
const res = await app.inject({
|
|
68
|
+
method: 'GET',
|
|
69
|
+
url: `${prefix}/cms-manager/${testTemplate}`,
|
|
70
|
+
});
|
|
71
|
+
assert.equal(res.statusCode, 200);
|
|
72
|
+
const rep = res.json();
|
|
73
|
+
// console.log(rep);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await t.test('GET /cms-manager/:type/:id', async () => {
|
|
77
|
+
const res = await app.inject({
|
|
78
|
+
method: 'GET',
|
|
79
|
+
url: `${prefix}/cms-manager/${testTemplate}/${testContentId}`,
|
|
80
|
+
});
|
|
81
|
+
assert.equal(res.statusCode, 200);
|
|
82
|
+
const rep = res.json();
|
|
83
|
+
// console.log(rep);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
await t.test('DELETE /cms-manager/:id', async () => {
|
|
88
|
+
const res = await app.inject({
|
|
89
|
+
method: 'DELETE',
|
|
90
|
+
url: `${prefix}/cms-manager/${testContentId}`,
|
|
91
|
+
});
|
|
92
|
+
assert.equal(res.statusCode, 200);
|
|
93
|
+
const rep = res.json();
|
|
94
|
+
// console.log(rep);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await t.test('clean up', async () => {
|
|
98
|
+
const { rowCount: contentCount } = await pg.query('delete from site.contents where content_id=$1', [testContentId]);
|
|
99
|
+
// const { rowCount: typeCount } = await pg.query('delete from site.content_types where content_type_id=$1', [testTypeId]);
|
|
100
|
+
// const { rowCount: categoryCount } = await pg.query('delete from site.categories where category_id=$1', [testCategoryId]);
|
|
101
|
+
console.log('clean up', contentCount);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { test } from 'node:test';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { readFile, rm } from 'node:fs/promises';
|
|
5
|
+
|
|
6
|
+
import { config, pgClients, getFolder } from '@opengis/fastify-table/utils.js';
|
|
7
|
+
|
|
8
|
+
import build from '../helper.js';
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
|
|
11
|
+
function arrayBufferToBlob(buffer, contentType) {
|
|
12
|
+
const uInt8Array = new Uint8Array(buffer);
|
|
13
|
+
return new Blob([uInt8Array], (contentType ? { type: contentType } : {}));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { prefix = '/api' } = config;
|
|
17
|
+
|
|
18
|
+
const uid = '1';
|
|
19
|
+
|
|
20
|
+
const tokens = {};
|
|
21
|
+
const ids = [];
|
|
22
|
+
const rootDir = getFolder(config, 'local');
|
|
23
|
+
const dir = 'testdirname';
|
|
24
|
+
const subdirname = 'subdirname';
|
|
25
|
+
|
|
26
|
+
test('cms manager api', async (t) => {
|
|
27
|
+
const app = await build(t);
|
|
28
|
+
|
|
29
|
+
app.addHook('onRequest', async (req) => {
|
|
30
|
+
req.session = { passport: { user: { user_type: 'admin', uid: '1' } } };
|
|
31
|
+
req.user = req.session.passport.user;
|
|
32
|
+
req.unittest = 1;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await t.test('GET /media (list)', async () => {
|
|
36
|
+
const res = await app.inject({
|
|
37
|
+
method: 'GET',
|
|
38
|
+
url: `${prefix}/cms-media`,
|
|
39
|
+
});
|
|
40
|
+
assert.equal(res.statusCode, 200);
|
|
41
|
+
const rep = res.json();
|
|
42
|
+
assert.ok(rep.token);
|
|
43
|
+
Object.assign(tokens, { root: rep.token });
|
|
44
|
+
assert.ok(rep.data);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await t.test('POST /cms-media/:token (add directory)', async () => {
|
|
48
|
+
// create directory
|
|
49
|
+
const res = await app.inject({
|
|
50
|
+
method: 'POST',
|
|
51
|
+
url: `${prefix}/cms-media/${tokens.root}`,
|
|
52
|
+
body: {
|
|
53
|
+
name: dir,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
assert.equal(res.statusCode, 200);
|
|
57
|
+
const rep = res.json();
|
|
58
|
+
assert.equal(rep.name, dir);
|
|
59
|
+
assert.ok(rep.token);
|
|
60
|
+
Object.assign(tokens, { dir: rep.token });
|
|
61
|
+
|
|
62
|
+
// create subdirectory
|
|
63
|
+
const res1 = await app.inject({
|
|
64
|
+
method: 'POST',
|
|
65
|
+
url: `${prefix}/cms-media/${tokens.dir}`,
|
|
66
|
+
body: {
|
|
67
|
+
name: subdirname,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
assert.equal(res1.statusCode, 200);
|
|
71
|
+
const rep1 = res1.json();
|
|
72
|
+
assert.ok(rep1.token);
|
|
73
|
+
assert.equal(rep1.name, subdirname);
|
|
74
|
+
assert.equal(rep1.dir, path.join('/media', dir, subdirname).replace(/\\/g, '/'));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await t.test('POST /cms-media/:token (upload file)', async () => {
|
|
78
|
+
const formdata = new FormData();
|
|
79
|
+
const filepath = path.join(process.cwd(), 'test/files/eye.svg');
|
|
80
|
+
const buffer = await readFile(filepath, { buffer: true });
|
|
81
|
+
const data = arrayBufferToBlob(buffer);
|
|
82
|
+
formdata.append('file', data, path.basename(filepath));
|
|
83
|
+
|
|
84
|
+
const res = await app.inject({
|
|
85
|
+
method: 'POST',
|
|
86
|
+
url: `${prefix}/cms-media/${tokens.dir}`,
|
|
87
|
+
body: formdata,
|
|
88
|
+
});
|
|
89
|
+
assert.equal(res.statusCode, 200);
|
|
90
|
+
const rep = res.json();
|
|
91
|
+
assert.ok(rep.token);
|
|
92
|
+
assert.ok(rep.id, 'insert error (crm.media table exists?)');
|
|
93
|
+
ids.push(rep.id);
|
|
94
|
+
Object.assign(tokens, { file: rep.token });
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await t.test('GET /cms-media/:token (preview file)', async () => {
|
|
98
|
+
const res = await app.inject({
|
|
99
|
+
method: 'GET',
|
|
100
|
+
url: `${prefix}/cms-media/${tokens.file}`,
|
|
101
|
+
});
|
|
102
|
+
assert.equal(res.statusCode, 200);
|
|
103
|
+
assert.equal(res.headers['content-type'], "image/svg+xml");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await t.test('GET /cms-media/:token (download file)', async () => {
|
|
107
|
+
const res = await app.inject({
|
|
108
|
+
method: 'GET',
|
|
109
|
+
url: `${prefix}/cms-media/${tokens.file}`,
|
|
110
|
+
query: { download: 1 },
|
|
111
|
+
});
|
|
112
|
+
assert.equal(res.statusCode, 200);
|
|
113
|
+
assert.ok(res.headers['content-disposition']?.startsWith('attachment'), 'no attachment on download');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
await t.test('GET /cms-media-metadata/:token (file metadata by token)', async () => {
|
|
117
|
+
const res = await app.inject({
|
|
118
|
+
method: 'GET',
|
|
119
|
+
url: `${prefix}/cms-media-metadata/${tokens.file}`,
|
|
120
|
+
});
|
|
121
|
+
assert.equal(res.statusCode, 200);
|
|
122
|
+
const rep = res.json();
|
|
123
|
+
assert.ok(rep.id);
|
|
124
|
+
assert.ok(rep.name);
|
|
125
|
+
assert.ok(rep.size);
|
|
126
|
+
assert.ok(rep.extension);
|
|
127
|
+
assert.ok(rep.ctime);
|
|
128
|
+
assert.ok(rep.mtime);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await t.test('GET /cms-media-metadata/:id (file metadata by id)', async () => {
|
|
132
|
+
const res = await app.inject({
|
|
133
|
+
method: 'GET',
|
|
134
|
+
url: `${prefix}/cms-media-metadata/${ids[0]}`,
|
|
135
|
+
});
|
|
136
|
+
assert.equal(res.statusCode, 200);
|
|
137
|
+
const rep = res.json();
|
|
138
|
+
assert.ok(rep.id);
|
|
139
|
+
assert.ok(rep.name);
|
|
140
|
+
assert.ok(rep.size);
|
|
141
|
+
assert.ok(rep.extension);
|
|
142
|
+
assert.ok(rep.ctime);
|
|
143
|
+
assert.ok(rep.mtime);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await t.test('PUT /cms-media/:token (edit file metadata by token)', async () => {
|
|
147
|
+
const res = await app.inject({
|
|
148
|
+
method: 'PUT',
|
|
149
|
+
url: `${prefix}/cms-media/${tokens.file}`,
|
|
150
|
+
body: {
|
|
151
|
+
name: '123.svg',
|
|
152
|
+
caption: 'Icon',
|
|
153
|
+
altname: 'image alt name',
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
assert.equal(res.statusCode, 200);
|
|
157
|
+
const rep = res.json();
|
|
158
|
+
assert.ok(rep);
|
|
159
|
+
assert.ok(rep.name, '123.svg');
|
|
160
|
+
assert.ok(rep.caption, 'Icon');
|
|
161
|
+
assert.ok(rep.altname, 'image alt name');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
await t.test('PUT /cms-media/:id (edit file metadata by id)', async () => {
|
|
165
|
+
const res = await app.inject({
|
|
166
|
+
method: 'PUT',
|
|
167
|
+
url: `${prefix}/cms-media/${ids[0]}`,
|
|
168
|
+
body: {
|
|
169
|
+
name: '1234.svg',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
assert.equal(res.statusCode, 200);
|
|
173
|
+
const rep = res.json();
|
|
174
|
+
assert.ok(rep.name, '1234.svg');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// rename directory
|
|
178
|
+
await t.test('PUT /cms-media/:id (rename directory)', async () => {
|
|
179
|
+
const res = await app.inject({
|
|
180
|
+
method: 'PUT',
|
|
181
|
+
url: `${prefix}/cms-media/${tokens.dir}`,
|
|
182
|
+
body: {
|
|
183
|
+
name: `${dir}1`,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
assert.equal(res.statusCode, 200);
|
|
187
|
+
const rep = res.json();
|
|
188
|
+
assert.equal(rep.name, `${dir}1`);
|
|
189
|
+
assert.equal(rep.relpath, path.join('/media', `${dir}1`).replace(/\\/g, '/'));
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// delete file
|
|
193
|
+
await t.test('DELETE /cms-media/:token (delete file by token)', async () => {
|
|
194
|
+
const res1 = await app.inject({
|
|
195
|
+
method: 'GET',
|
|
196
|
+
url: `${prefix}/cms-media`,
|
|
197
|
+
query: { dir: `${dir}1` },
|
|
198
|
+
});
|
|
199
|
+
assert.equal(res1.statusCode, 200);
|
|
200
|
+
const rep1 = res1.json();
|
|
201
|
+
assert.ok(rep1.data);
|
|
202
|
+
const newtokens = rep1.data.reduce((acc, curr) => Object.assign(acc, { [curr.type]: curr.token }), {});
|
|
203
|
+
Object.assign(tokens, { new: newtokens });
|
|
204
|
+
assert.ok(Object.keys(tokens.new).length, 'empty directory');
|
|
205
|
+
|
|
206
|
+
const res = await app.inject({
|
|
207
|
+
method: 'DELETE',
|
|
208
|
+
url: `${prefix}/cms-media/${newtokens.file}`,
|
|
209
|
+
});
|
|
210
|
+
assert.equal(res.statusCode, 200);
|
|
211
|
+
const rep = res.json();
|
|
212
|
+
assert.ok(rep.id);
|
|
213
|
+
assert.equal(rep.name, '1234.svg');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// delete directory
|
|
217
|
+
await t.test('DELETE /cms-media/:token (delete directory by token)', async () => {
|
|
218
|
+
const dirpath = path.join(rootDir, 'media', `${dir}1`, subdirname);
|
|
219
|
+
const existsBefore = existsSync(dirpath);
|
|
220
|
+
const res = await app.inject({
|
|
221
|
+
method: 'DELETE',
|
|
222
|
+
url: `${prefix}/cms-media/${tokens.new.dir}`,
|
|
223
|
+
});
|
|
224
|
+
assert.equal(res.statusCode, 200);
|
|
225
|
+
const existsAfter = existsSync(dirpath);
|
|
226
|
+
assert.ok(existsBefore && !existsAfter);
|
|
227
|
+
});
|
|
228
|
+
// restrict delete root directory
|
|
229
|
+
await t.test('DELETE /cms-media/:token (restrict delete root directory)', async () => {
|
|
230
|
+
const res = await app.inject({
|
|
231
|
+
method: 'DELETE',
|
|
232
|
+
url: `${prefix}/cms-media/${tokens.root}`,
|
|
233
|
+
});
|
|
234
|
+
assert.equal(res.statusCode, 403);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
await t.test('clean up', async () => {
|
|
238
|
+
const { rowCount = 0 } = pgClients.client?.pk?.['crm.media'] ? await pgClients.client.query(`delete from crm.media where uid=$1`, [uid]) : {};
|
|
239
|
+
console.log('clean up: media', rowCount);
|
|
240
|
+
const dirpath = path.join(rootDir, 'media', dir);
|
|
241
|
+
const len = [dirpath, `${dirpath}1`].filter(el => existsSync(el)).length;
|
|
242
|
+
if (len > 0) {
|
|
243
|
+
await Promise.all([dirpath, `${dirpath}1`].filter(el => existsSync(el)).map(async (el) => {
|
|
244
|
+
console.log('clean up: test directory', el);
|
|
245
|
+
await rm(el, { recursive: true });
|
|
246
|
+
}));
|
|
247
|
+
} else {
|
|
248
|
+
console.log('clean up: test directory', 0);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
});
|