museria 0.2.49 → 0.3.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/.eslintrc +10 -2
- package/.github/workflows/build.yml +3 -3
- package/.github/workflows/publish.yml +3 -3
- package/README.md +55 -59
- package/bin/actions.js +28 -28
- package/bin/index.js +4 -4
- package/bin/runner.js +1 -1
- package/bin/utils.js +6 -2
- package/dist/client/museria.client.js +7 -7
- package/dist/face/45a265d0f07b31cde85f.ttf +0 -0
- package/dist/face/6205fd00fb1b573e9f0f.ttf +0 -0
- package/dist/face/8d3cabfc66809162fb4d.woff2 +0 -0
- package/dist/face/fb8184add5a3101ad0a3.woff2 +0 -0
- package/dist/face/museria.face.js +33 -13
- package/dist/face/style.css +13 -11
- package/package.json +41 -40
- package/src/browser/client/index.js +2 -1
- package/src/browser/face/client.js +2 -1
- package/src/browser/face/controllers/app/app.html +77 -69
- package/src/browser/face/controllers/app/app.js +14 -7
- package/src/browser/face/controllers/app/app.scss +2 -22
- package/src/browser/face/index.js +3 -3
- package/src/browser/face/styles/main.scss +91 -11
- package/src/browser/face/styles/vars.scss +0 -1
- package/src/client.js +73 -74
- package/src/collection/transports/music/index.js +20 -18
- package/src/db/transports/database/index.js +7 -5
- package/src/db/transports/loki/index.js +30 -25
- package/src/errors.js +2 -1
- package/src/index.js +8 -6
- package/src/node.js +312 -323
- package/src/schema.js +27 -29
- package/src/server/transports/express/api/butler/controllers.js +7 -10
- package/src/server/transports/express/api/butler/routes.js +5 -5
- package/src/server/transports/express/api/master/controllers.js +7 -10
- package/src/server/transports/express/api/master/routes.js +5 -5
- package/src/server/transports/express/api/node/controllers.js +52 -61
- package/src/server/transports/express/api/node/routes.js +10 -10
- package/src/server/transports/express/api/routes.js +1 -1
- package/src/server/transports/express/api/slave/controllers.js +7 -10
- package/src/server/transports/express/api/slave/routes.js +6 -6
- package/src/server/transports/express/client/controllers.js +40 -61
- package/src/server/transports/express/client/routes.js +33 -39
- package/src/server/transports/express/controllers.js +10 -21
- package/src/server/transports/express/index.js +23 -20
- package/src/server/transports/express/midds.js +67 -67
- package/src/server/transports/express/routes.js +12 -12
- package/src/utils.js +175 -184
- package/test/client.js +311 -305
- package/test/db/database.js +32 -28
- package/test/db/loki.js +78 -74
- package/test/group.js +161 -156
- package/test/index.js +20 -10
- package/test/node.js +461 -460
- package/test/routes.js +404 -399
- package/test/server/express.js +35 -31
- package/test/services.js +25 -18
- package/test/tools.js +8 -6
- package/test/utils.js +236 -234
- package/webpack.client.js +9 -7
- package/webpack.face.js +8 -6
- package/dist/face/fa-brands-400.eot +0 -0
- package/dist/face/fa-brands-400.svg +0 -3717
- package/dist/face/fa-brands-400.ttf +0 -0
- package/dist/face/fa-brands-400.woff +0 -0
- package/dist/face/fa-brands-400.woff2 +0 -0
- package/dist/face/fa-solid-900.eot +0 -0
- package/dist/face/fa-solid-900.svg +0 -5034
- package/dist/face/fa-solid-900.ttf +0 -0
- package/dist/face/fa-solid-900.woff +0 -0
- package/dist/face/fa-solid-900.woff2 +0 -0
- /package/dist/face/{open-sans.ttf → 17e98b9e5586529b13cc.ttf} +0 -0
- /package/dist/face/{proxima-nova.ttf → 326601dfabd91e3f016c.ttf} +0 -0
- /package/dist/face/{logo.svg → ee9c6af64aa224827cec.svg} +0 -0
package/test/routes.js
CHANGED
@@ -1,471 +1,476 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
node
|
17
|
-
|
1
|
+
import { assert } from "chai";
|
2
|
+
import fse from "fs-extra";
|
3
|
+
import path from "path";
|
4
|
+
import fetch from "node-fetch";
|
5
|
+
import node from "../src/node.js";
|
6
|
+
import client from "../src/client.js";
|
7
|
+
import utils from "../src/utils.js";
|
8
|
+
import schema from "../src/schema.js";
|
9
|
+
import tools from "./tools.js";
|
10
|
+
|
11
|
+
const Node = node();
|
12
|
+
const Client = client();
|
13
|
+
|
14
|
+
export default function () {
|
15
|
+
describe('routes', () => {
|
16
|
+
let node;
|
17
|
+
let client;
|
18
|
+
|
19
|
+
before(async function () {
|
20
|
+
node = new Node(await tools.createNodeOptions({
|
21
|
+
network: {
|
22
|
+
auth: { username: 'username', password: 'password' }
|
23
|
+
}
|
24
|
+
}));
|
25
|
+
await node.init();
|
26
|
+
client = new Client(await tools.createClientOptions({
|
27
|
+
address: node.address,
|
18
28
|
auth: { username: 'username', password: 'password' }
|
19
|
-
}
|
20
|
-
|
21
|
-
|
22
|
-
client = new Client(await tools.createClientOptions({
|
23
|
-
address: node.address,
|
24
|
-
auth: { username: 'username', password: 'password' }
|
25
|
-
}));
|
26
|
-
await client.init();
|
27
|
-
});
|
28
|
-
|
29
|
-
after(async function() {
|
30
|
-
await node.deinit();
|
31
|
-
await client.deinit();
|
32
|
-
});
|
29
|
+
}));
|
30
|
+
await client.init();
|
31
|
+
});
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
assert.equal(await res.status, 401);
|
33
|
+
after(async function () {
|
34
|
+
await node.deinit();
|
35
|
+
await client.deinit();
|
38
36
|
});
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
assert.doesNotThrow(() => {
|
45
|
-
utils.validateSchema(schema.getStatusResponse(), json);
|
38
|
+
describe('/status', function () {
|
39
|
+
it('should return an auth error', async function () {
|
40
|
+
const res = await fetch(`http://${node.address}/status`);
|
41
|
+
assert.equal(await res.status, 401);
|
46
42
|
});
|
47
|
-
});
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
it('should return the status', async function () {
|
45
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
46
|
+
const res = await fetch(`http://${node.address}/status`, options);
|
47
|
+
const json = await res.json();
|
48
|
+
assert.doesNotThrow(() => {
|
49
|
+
utils.validateSchema(schema.getStatusResponse(), json);
|
50
|
+
});
|
55
51
|
});
|
56
|
-
});
|
57
|
-
});
|
58
52
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
it('should return the pretty status', async function () {
|
54
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
55
|
+
const res = await fetch(`http://${node.address}/status?pretty`, options);
|
56
|
+
const json = await res.json();
|
57
|
+
assert.doesNotThrow(() => {
|
58
|
+
utils.validateSchema(schema.getStatusPrettyResponse(), json);
|
59
|
+
});
|
60
|
+
});
|
63
61
|
});
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
describe('/audio/:hash', function () {
|
64
|
+
it('should return an auth error', async function () {
|
65
|
+
const res = await fetch(`http://${node.address}/audio/hash`);
|
66
|
+
assert.equal(await res.status, 401);
|
67
|
+
});
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
const code = utils.encodeSongTitle(doc.title);
|
77
|
-
const buffer = await fse.readFile(node.getFilePath(doc.fileHash));
|
78
|
-
const filePath = path.join(tools.tmpPath, 'audio-saved.mp3');
|
79
|
-
const options = client.createDefaultRequestOptions({ method: 'get' });
|
80
|
-
const res = await fetch(`http://${node.address}/audio/${ code }?${doc.fileHash}`, options);
|
81
|
-
await tools.saveResponseToFile(res, filePath);
|
82
|
-
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
83
|
-
});
|
84
|
-
});
|
69
|
+
it('should return 404', async function () {
|
70
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
71
|
+
const res = await fetch(`http://${node.address}/audio/wrong-hash`, options);
|
72
|
+
assert.equal(res.status, 404);
|
73
|
+
});
|
85
74
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
75
|
+
it('should return the file', async function () {
|
76
|
+
const title = 'artist - title';
|
77
|
+
const file = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle: title });
|
78
|
+
await node.addSong(file);
|
79
|
+
const doc = await node.db.getMusicByPk(title);
|
80
|
+
const code = utils.encodeSongTitle(doc.title);
|
81
|
+
const buffer = await fse.readFile(node.getFilePath(doc.fileHash));
|
82
|
+
const filePath = path.join(tools.tmpPath, 'audio-saved.mp3');
|
83
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
84
|
+
const res = await fetch(`http://${node.address}/audio/${code}?${doc.fileHash}`, options);
|
85
|
+
await tools.saveResponseToFile(res, filePath);
|
86
|
+
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
87
|
+
});
|
90
88
|
});
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
describe('/cover/:hash', function () {
|
91
|
+
it('should return an auth error', async function () {
|
92
|
+
const res = await fetch(`http://${node.address}/cover/hash`);
|
93
|
+
assert.equal(await res.status, 401);
|
94
|
+
});
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
});
|
104
|
-
await node.addSong(file);
|
105
|
-
const doc = await node.db.getMusicByPk(title);
|
106
|
-
const code = utils.encodeSongTitle(doc.title);
|
107
|
-
const buffer = (await utils.getSongTags(node.getFilePath(doc.fileHash))).APIC
|
108
|
-
const filePath = path.join(tools.tmpPath, 'cover-saved.jpg');
|
109
|
-
const options = client.createDefaultRequestOptions({ method: 'get' });
|
110
|
-
const res = await fetch(`http://${node.address}/cover/${ code }?${doc.fileHash}`, options);
|
111
|
-
await tools.saveResponseToFile(res, filePath);
|
112
|
-
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
113
|
-
});
|
114
|
-
});
|
96
|
+
it('should return 404', async function () {
|
97
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
98
|
+
const res = await fetch(`http://${node.address}/cover/wrong-hash`, options);
|
99
|
+
assert.equal(res.status, 404);
|
100
|
+
});
|
115
101
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
102
|
+
it('should return the file', async function () {
|
103
|
+
const title = 'artist - title';
|
104
|
+
const file = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), {
|
105
|
+
fullTitle: title,
|
106
|
+
APIC: path.join(tools.tmpPath, 'cover.jpg')
|
107
|
+
});
|
108
|
+
await node.addSong(file);
|
109
|
+
const doc = await node.db.getMusicByPk(title);
|
110
|
+
const code = utils.encodeSongTitle(doc.title);
|
111
|
+
const buffer = (await utils.getSongTags(node.getFilePath(doc.fileHash))).APIC;
|
112
|
+
const filePath = path.join(tools.tmpPath, 'cover-saved.jpg');
|
113
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
114
|
+
const res = await fetch(`http://${node.address}/cover/${code}?${doc.fileHash}`, options);
|
115
|
+
await tools.saveResponseToFile(res, filePath);
|
116
|
+
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
117
|
+
});
|
120
118
|
});
|
121
119
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
});
|
120
|
+
describe('/client/request-song', function () {
|
121
|
+
it('should return an auth error', async function () {
|
122
|
+
const res = await fetch(`http://${node.address}/client/request-song`, { method: 'get' });
|
123
|
+
assert.equal(await res.status, 401);
|
124
|
+
});
|
128
125
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
126
|
+
it('should return an error because of a wrong title', async function () {
|
127
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
128
|
+
const res = await fetch(`http://${node.address}/client/request-song/?type=audio`, options);
|
129
|
+
assert.equal(res.status, 422, 'check the status');
|
130
|
+
assert.isOk((await res.json()).message.match('Wrong song title'), 'check the message');
|
131
|
+
});
|
135
132
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
133
|
+
it('should return an error because of a wrong type', async function () {
|
134
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
135
|
+
const res = await fetch(`http://${node.address}/client/request-song/?title=artist - title`, options);
|
136
|
+
assert.equal(res.status, 422, 'check the status');
|
137
|
+
assert.isOk((await res.json()).message.match('Link type'), 'check the message');
|
138
|
+
});
|
141
139
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
140
|
+
it('should return 404 for audio', async function () {
|
141
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
142
|
+
const res = await fetch(`http://${node.address}/client/request-song/?title=unexistent - song&type=audio`, options);
|
143
|
+
assert.equal(res.status, 404);
|
144
|
+
});
|
147
145
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
const options = client.createDefaultRequestOptions({ method: 'get' });
|
154
|
-
const res = await fetch(`http://${node.address}/client/request-song/?title=${title}&type=audio`, options);
|
155
|
-
await tools.saveResponseToFile(res, filePath);
|
156
|
-
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
157
|
-
});
|
146
|
+
it('should return 404 for cover', async function () {
|
147
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
148
|
+
const res = await fetch(`http://${node.address}/client/request-song/?title=unexistent - song&type=cover`, options);
|
149
|
+
assert.equal(res.status, 404);
|
150
|
+
});
|
158
151
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
});
|
152
|
+
it('should return the audio file', async function () {
|
153
|
+
const title = 'artist - title';
|
154
|
+
const doc = await node.db.getMusicByPk(title);
|
155
|
+
const buffer = await fse.readFile(node.getFilePath(doc.fileHash));
|
156
|
+
const filePath = path.join(tools.tmpPath, 'audio-saved.mp3');
|
157
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
158
|
+
const res = await fetch(`http://${node.address}/client/request-song/?title=${title}&type=audio`, options);
|
159
|
+
await tools.saveResponseToFile(res, filePath);
|
160
|
+
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
161
|
+
});
|
170
162
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
163
|
+
it('should return the cover file', async function () {
|
164
|
+
const title = 'artist - title';
|
165
|
+
const doc = await node.db.getMusicByPk(title);
|
166
|
+
const buffer = (await utils.getSongTags(node.getFilePath(doc.fileHash))).APIC;
|
167
|
+
const filePath = path.join(tools.tmpPath, 'cover-saved.jpg');
|
168
|
+
const options = client.createDefaultRequestOptions({ method: 'get' });
|
169
|
+
const res = await fetch(`http://${node.address}/client/request-song/?title=${title}&type=cover`, options);
|
170
|
+
await tools.saveResponseToFile(res, filePath);
|
171
|
+
assert.isOk(Buffer.compare(await fse.readFile(filePath), buffer) == 0);
|
172
|
+
});
|
175
173
|
});
|
176
174
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
175
|
+
describe('/client/add-song', function () {
|
176
|
+
it('should return an auth error', async function () {
|
177
|
+
const res = await fetch(`http://${node.address}/client/add-song`, { method: 'post' });
|
178
|
+
assert.equal(await res.status, 401);
|
179
|
+
});
|
182
180
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
TIT3: 'x'
|
189
|
-
});
|
190
|
-
const fileOptions = { contentType: 'audio/mpeg', filename: `audio.mp3` };
|
191
|
-
const body = tools.createRequestFormData({
|
192
|
-
file: { value: fse.createReadStream(file), options: fileOptions }
|
193
|
-
});
|
194
|
-
const options = client.createDefaultRequestOptions({ body });
|
195
|
-
const res = await fetch(`http://${node.address}/client/add-song`, options);
|
196
|
-
const json = await res.json();
|
197
|
-
const doc = await node.db.getMusicByPk(title);
|
198
|
-
assert.isNotNull(doc, 'check the database');
|
199
|
-
assert.equal(utils.beautifySongTitle(title), json.title, 'check the title');
|
200
|
-
assert.equal(json.tags.TIT3, 'x', 'check the tags');
|
201
|
-
assert.isTrue(await node.hasFile(doc.fileHash), 'check the file');
|
202
|
-
assert.isTrue(utils.isValidSongAudioLink(json.audioLink), 'check the audio link');
|
203
|
-
assert.isTrue(utils.isValidSongCoverLink(json.coverLink), 'check the cover link');
|
204
|
-
});
|
205
|
-
});
|
181
|
+
it('should return an error', async function () {
|
182
|
+
const options = client.createDefaultRequestOptions();
|
183
|
+
const res = await fetch(`http://${node.address}/client/add-song`, options);
|
184
|
+
assert.equal(res.status, 422);
|
185
|
+
});
|
206
186
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
187
|
+
it('should save the song', async function () {
|
188
|
+
const title = 'new - song';
|
189
|
+
const file = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), {
|
190
|
+
fullTitle: title,
|
191
|
+
APIC: path.join(tools.tmpPath, 'cover.jpg'),
|
192
|
+
TIT3: 'x'
|
193
|
+
});
|
194
|
+
const fileOptions = { contentType: 'audio/mpeg', filename: `audio.mp3` };
|
195
|
+
const body = tools.createRequestFormData({
|
196
|
+
file: { value: fse.createReadStream(file), options: fileOptions }
|
197
|
+
});
|
198
|
+
const options = client.createDefaultRequestOptions({ body });
|
199
|
+
const res = await fetch(`http://${node.address}/client/add-song`, options);
|
200
|
+
const json = await res.json();
|
201
|
+
const doc = await node.db.getMusicByPk(title);
|
202
|
+
assert.isNotNull(doc, 'check the database');
|
203
|
+
assert.equal(utils.beautifySongTitle(title), json.title, 'check the title');
|
204
|
+
assert.equal(json.tags.TIT3, 'x', 'check the tags');
|
205
|
+
assert.isTrue(await node.hasFile(doc.fileHash), 'check the file');
|
206
|
+
assert.isTrue(utils.isValidSongAudioLink(json.audioLink), 'check the audio link');
|
207
|
+
assert.isTrue(utils.isValidSongCoverLink(json.coverLink), 'check the cover link');
|
208
|
+
});
|
211
209
|
});
|
212
210
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
211
|
+
describe('/client/get-song-info', function () {
|
212
|
+
it('should return an auth error', async function () {
|
213
|
+
const res = await fetch(`http://${node.address}/client/get-song-info`, { method: 'post' });
|
214
|
+
assert.equal(await res.status, 401);
|
215
|
+
});
|
218
216
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
const info = json.info[0];
|
225
|
-
assert.lengthOf(json.info, 1, 'check the length');
|
226
|
-
assert.equal(utils.beautifySongTitle(title), info.title, 'check the title');
|
227
|
-
assert.equal(info.tags.TIT3, 'x', 'check the tags');
|
228
|
-
assert.isTrue(utils.isValidSongAudioLink(info.audioLink), 'check the audio link');
|
229
|
-
assert.isTrue(utils.isValidSongCoverLink(info.coverLink), 'check the cover link');
|
230
|
-
});
|
231
|
-
});
|
217
|
+
it('should return an error', async function () {
|
218
|
+
const options = client.createDefaultRequestOptions({ method: 'post' });
|
219
|
+
const res = await fetch(`http://${node.address}/client/get-song-info`, options);
|
220
|
+
assert.equal(res.status, 422);
|
221
|
+
});
|
232
222
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
223
|
+
it('should return the info', async function () {
|
224
|
+
const title = 'new - song';
|
225
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body: { title } }));
|
226
|
+
const res = await fetch(`http://${node.address}/client/get-song-info`, options);
|
227
|
+
const json = await res.json();
|
228
|
+
const info = json.info[0];
|
229
|
+
assert.lengthOf(json.info, 1, 'check the length');
|
230
|
+
assert.equal(utils.beautifySongTitle(title), info.title, 'check the title');
|
231
|
+
assert.equal(info.tags.TIT3, 'x', 'check the tags');
|
232
|
+
assert.isTrue(utils.isValidSongAudioLink(info.audioLink), 'check the audio link');
|
233
|
+
assert.isTrue(utils.isValidSongCoverLink(info.coverLink), 'check the cover link');
|
234
|
+
});
|
237
235
|
});
|
238
236
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
const songs = json.songs[0];
|
245
|
-
assert.lengthOf(json.songs, 1, 'check the length');
|
246
|
-
assert.isOk(songs.title.toLowerCase().match(str.toLowerCase()), 'check the title');
|
247
|
-
assert.equal(songs.tags.TIT3, 'x', 'check the tags');
|
248
|
-
assert.isTrue(utils.isValidSongAudioLink(songs.audioLink), 'check the audio link');
|
249
|
-
assert.isTrue(utils.isValidSongCoverLink(songs.coverLink), 'check the cover link');
|
250
|
-
});
|
251
|
-
});
|
237
|
+
describe('/client/find-songs', function () {
|
238
|
+
it('should return an auth error', async function () {
|
239
|
+
const res = await fetch(`http://${node.address}/client/find-songs`, { method: 'post' });
|
240
|
+
assert.equal(await res.status, 401);
|
241
|
+
});
|
252
242
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
243
|
+
it('should return the songs', async function () {
|
244
|
+
const str = 'new - song';
|
245
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body: { str } }));
|
246
|
+
const res = await fetch(`http://${node.address}/client/find-songs`, options);
|
247
|
+
const json = await res.json();
|
248
|
+
const songs = json.songs[0];
|
249
|
+
assert.lengthOf(json.songs, 1, 'check the length');
|
250
|
+
assert.isOk(songs.title.toLowerCase().match(str.toLowerCase()), 'check the title');
|
251
|
+
assert.equal(songs.tags.TIT3, 'x', 'check the tags');
|
252
|
+
assert.isTrue(utils.isValidSongAudioLink(songs.audioLink), 'check the audio link');
|
253
|
+
assert.isTrue(utils.isValidSongCoverLink(songs.coverLink), 'check the cover link');
|
254
|
+
});
|
257
255
|
});
|
258
256
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
const songs = json.songs[0];
|
265
|
-
assert.lengthOf(json.songs, 1, 'check the length');
|
266
|
-
assert.isOk(songs.title.toLowerCase().match(artist.toLowerCase()), 'check the title');
|
267
|
-
assert.equal(songs.tags.TIT3, 'x', 'check the tags');
|
268
|
-
assert.isTrue(utils.isValidSongAudioLink(songs.audioLink), 'check the audio link');
|
269
|
-
assert.isTrue(utils.isValidSongCoverLink(songs.coverLink), 'check the cover link');
|
270
|
-
});
|
271
|
-
});
|
257
|
+
describe('/client/find-artist-songs', function () {
|
258
|
+
it('should return an auth error', async function () {
|
259
|
+
const res = await fetch(`http://${node.address}/client/find-artist-songs`, { method: 'post' });
|
260
|
+
assert.equal(await res.status, 401);
|
261
|
+
});
|
272
262
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
263
|
+
it('should return the songs', async function () {
|
264
|
+
const artist = 'new';
|
265
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body: { artist } }));
|
266
|
+
const res = await fetch(`http://${node.address}/client/find-artist-songs`, options);
|
267
|
+
const json = await res.json();
|
268
|
+
const songs = json.songs[0];
|
269
|
+
assert.lengthOf(json.songs, 1, 'check the length');
|
270
|
+
assert.isOk(songs.title.toLowerCase().match(artist.toLowerCase()), 'check the title');
|
271
|
+
assert.equal(songs.tags.TIT3, 'x', 'check the tags');
|
272
|
+
assert.isTrue(utils.isValidSongAudioLink(songs.audioLink), 'check the audio link');
|
273
|
+
assert.isTrue(utils.isValidSongCoverLink(songs.coverLink), 'check the cover link');
|
274
|
+
});
|
277
275
|
});
|
278
276
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
assert.isOk((await res.json()).message.match('Wrong song title'), 'check the message');
|
285
|
-
});
|
277
|
+
describe('/client/get-song-link', function () {
|
278
|
+
it('should return an auth error', async function () {
|
279
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, { method: 'post' });
|
280
|
+
assert.equal(await res.status, 401);
|
281
|
+
});
|
286
282
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
283
|
+
it('should return an error because of a wrong title', async function () {
|
284
|
+
const body = { type: 'audio' };
|
285
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
286
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
287
|
+
assert.equal(res.status, 422, 'check the status');
|
288
|
+
assert.isOk((await res.json()).message.match('Wrong song title'), 'check the message');
|
289
|
+
});
|
294
290
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
291
|
+
it('should return an error because of a wrong type', async function () {
|
292
|
+
const body = { title: 'new - song' };
|
293
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
294
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
295
|
+
assert.equal(res.status, 422, 'check the status');
|
296
|
+
assert.isOk((await res.json()).message.match('Link type'), 'check the message');
|
297
|
+
});
|
298
|
+
|
299
|
+
it('should return an empty audio link', async function () {
|
300
|
+
const body = { title: 'unexistent - unexistent', type: 'audio' };
|
301
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
302
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
303
|
+
const json = await res.json();
|
304
|
+
assert.isEmpty(json.link);
|
305
|
+
});
|
302
306
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
307
|
+
it('should return an empty cover link', async function () {
|
308
|
+
const body = { title: 'unexistent - unexistent', type: 'cover' };
|
309
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
310
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
311
|
+
const json = await res.json();
|
312
|
+
assert.isEmpty(json.link);
|
313
|
+
});
|
310
314
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
315
|
+
it('should return the audio link', async function () {
|
316
|
+
const title = 'new - song';
|
317
|
+
const body = { title, type: 'audio' };
|
318
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
319
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
320
|
+
const json = await res.json();
|
321
|
+
assert.isTrue(utils.isValidSongAudioLink(json.link));
|
322
|
+
});
|
319
323
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
324
|
+
it('should return the cover link', async function () {
|
325
|
+
const title = 'new - song';
|
326
|
+
const body = { title, type: 'cover' };
|
327
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
328
|
+
const res = await fetch(`http://${node.address}/client/get-song-link`, options);
|
329
|
+
const json = await res.json();
|
330
|
+
assert.isTrue(utils.isValidSongCoverLink(json.link));
|
331
|
+
});
|
327
332
|
});
|
328
|
-
});
|
329
333
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
334
|
+
describe('/client/remove-song/', function () {
|
335
|
+
it('should return an auth error', async function () {
|
336
|
+
const res = await fetch(`http://${node.address}/client/remove-song/`, { method: 'post' });
|
337
|
+
assert.equal(await res.status, 401);
|
338
|
+
});
|
335
339
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
340
|
+
it('should return a data error', async function () {
|
341
|
+
const options = client.createDefaultRequestOptions();
|
342
|
+
const res = await fetch(`http://${node.address}/client/remove-song/`, options);
|
343
|
+
assert.equal(res.status, 422);
|
344
|
+
});
|
341
345
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
346
|
+
it('should not remove the file with priority 1', async function () {
|
347
|
+
const title = 'new - song';
|
348
|
+
const doc = await node.db.getMusicByPk(title);
|
349
|
+
doc.priority = 1;
|
350
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body: { title } }));
|
351
|
+
const res = await fetch(`http://${node.address}/client/remove-song/`, options);
|
352
|
+
const json = await res.json();
|
353
|
+
doc.priority = 0;
|
354
|
+
assert.equal(json.removed, 0, 'check the response');
|
355
|
+
assert.isTrue(await node.hasFile(doc.fileHash), 'check the file');
|
356
|
+
});
|
353
357
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
358
|
+
it('should remove the file', async function () {
|
359
|
+
const title = 'new - song';
|
360
|
+
const doc = await node.db.getMusicByPk(title);
|
361
|
+
const options = client.createDefaultRequestOptions(tools.createJsonRequestOptions({ body: { title } }));
|
362
|
+
const res = await fetch(`http://${node.address}/client/remove-song/`, options);
|
363
|
+
const json = await res.json();
|
364
|
+
assert.equal(json.removed, 1, 'check the response');
|
365
|
+
assert.isNull(await node.db.getMusicByPk(title), 'check the database');
|
366
|
+
assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
|
367
|
+
});
|
363
368
|
});
|
364
|
-
});
|
365
369
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
370
|
+
describe('/api/master/remove-song/', function () {
|
371
|
+
it('should return an auth error', async function () {
|
372
|
+
const res = await fetch(`http://${node.address}/api/master/remove-song/`, { method: 'post' });
|
373
|
+
assert.equal(await res.status, 401);
|
374
|
+
});
|
371
375
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
376
|
+
it('should return a data error', async function () {
|
377
|
+
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions());
|
378
|
+
const res = await fetch(`http://${node.address}/api/master/remove-song/`, options);
|
379
|
+
assert.equal(res.status, 422);
|
380
|
+
});
|
377
381
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
382
|
+
it('should return the right schema', async function () {
|
383
|
+
const body = {
|
384
|
+
level: 2,
|
385
|
+
title: 'artist - title'
|
386
|
+
};
|
387
|
+
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
388
|
+
const res = await fetch(`http://${node.address}/api/master/remove-song/`, options);
|
389
|
+
const json = tools.createServerResponse(node.address, await res.json());
|
390
|
+
assert.doesNotThrow(() => {
|
391
|
+
utils.validateSchema(schema.getSongRemovalMasterResponse(), json);
|
392
|
+
});
|
388
393
|
});
|
389
394
|
});
|
390
|
-
});
|
391
|
-
|
392
|
-
describe('/api/butler/remove-song/', function () {
|
393
|
-
it('should return an auth error', async function () {
|
394
|
-
const res = await fetch(`http://${node.address}/api/butler/remove-song/`, { method: 'post' });
|
395
|
-
assert.equal(await res.status, 401);
|
396
|
-
});
|
397
395
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
396
|
+
describe('/api/butler/remove-song/', function () {
|
397
|
+
it('should return an auth error', async function () {
|
398
|
+
const res = await fetch(`http://${node.address}/api/butler/remove-song/`, { method: 'post' });
|
399
|
+
assert.equal(await res.status, 401);
|
400
|
+
});
|
403
401
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
};
|
409
|
-
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
410
|
-
const res = await fetch(`http://${node.address}/api/butler/remove-song/`, options);
|
411
|
-
const json = tools.createServerResponse(node.address, await res.json());
|
412
|
-
assert.doesNotThrow(() => {
|
413
|
-
utils.validateSchema(schema.getSongRemovalButlerResponse(), json);
|
402
|
+
it('should return a data error', async function () {
|
403
|
+
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions());
|
404
|
+
const res = await fetch(`http://${node.address}/api/butler/remove-song/`, options);
|
405
|
+
assert.equal(res.status, 422);
|
414
406
|
});
|
415
|
-
});
|
416
|
-
});
|
417
407
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
408
|
+
it('should return the right schema', async function () {
|
409
|
+
const body = {
|
410
|
+
level: 1,
|
411
|
+
title: 'artist - title'
|
412
|
+
};
|
413
|
+
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
414
|
+
const res = await fetch(`http://${node.address}/api/butler/remove-song/`, options);
|
415
|
+
const json = tools.createServerResponse(node.address, await res.json());
|
416
|
+
assert.doesNotThrow(() => {
|
417
|
+
utils.validateSchema(schema.getSongRemovalButlerResponse(), json);
|
418
|
+
});
|
419
|
+
});
|
422
420
|
});
|
423
421
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
422
|
+
describe('/api/slave/remove-song/', function () {
|
423
|
+
it('should return an auth error', async function () {
|
424
|
+
const res = await fetch(`http://${node.address}/api/slave/remove-song/`, { method: 'post' });
|
425
|
+
assert.equal(await res.status, 401);
|
426
|
+
});
|
429
427
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
};
|
435
|
-
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
436
|
-
const res = await fetch(`http://${node.address}/api/slave/remove-song/`, options);
|
437
|
-
const json = tools.createServerResponse(node.address, await res.json());
|
438
|
-
assert.doesNotThrow(() => {
|
439
|
-
utils.validateSchema(schema.getSongRemovalSlaveResponse(), json);
|
428
|
+
it('should return a data error', async function () {
|
429
|
+
const options = node.createDefaultRequestOptions();
|
430
|
+
const res = await fetch(`http://${node.address}/api/slave/remove-song/`, options);
|
431
|
+
assert.equal(res.status, 422);
|
440
432
|
});
|
441
|
-
});
|
442
|
-
});
|
443
433
|
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
434
|
+
it('should return the right schema', async function () {
|
435
|
+
const body = {
|
436
|
+
level: 0,
|
437
|
+
title: 'artist - title'
|
438
|
+
};
|
439
|
+
const options = node.createDefaultRequestOptions(tools.createJsonRequestOptions({ body }));
|
440
|
+
const res = await fetch(`http://${node.address}/api/slave/remove-song/`, options);
|
441
|
+
const json = tools.createServerResponse(node.address, await res.json());
|
442
|
+
assert.doesNotThrow(() => {
|
443
|
+
utils.validateSchema(schema.getSongRemovalSlaveResponse(), json);
|
444
|
+
});
|
445
|
+
});
|
448
446
|
});
|
449
447
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
448
|
+
describe('/api/node/add-song/', function () {
|
449
|
+
it('should return an auth error', async function () {
|
450
|
+
const res = await fetch(`http://${node.address}/api/node/add-song/`, { method: 'post' });
|
451
|
+
assert.equal(await res.status, 401);
|
452
|
+
});
|
455
453
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
const body = tools.createRequestFormData({
|
461
|
-
file: { value: fse.createReadStream(file), options: fileOptions }
|
454
|
+
it('should return an error', async function () {
|
455
|
+
const options = node.createDefaultRequestOptions();
|
456
|
+
const res = await fetch(`http://${node.address}/api/node/add-song/`, options);
|
457
|
+
assert.equal(res.status, 422);
|
462
458
|
});
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
459
|
+
|
460
|
+
it('should return the right schema', async function () {
|
461
|
+
const fullTitle = 'new - song';
|
462
|
+
const file = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle });
|
463
|
+
const fileOptions = { contentType: 'audio/mpeg', filename: `audio.mp3` };
|
464
|
+
const body = tools.createRequestFormData({
|
465
|
+
file: { value: fse.createReadStream(file), options: fileOptions }
|
466
|
+
});
|
467
|
+
const options = node.createDefaultRequestOptions({ body });
|
468
|
+
const res = await fetch(`http://${node.address}/api/node/add-song/`, options);
|
469
|
+
const json = tools.createServerResponse(node.address, await res.json());
|
470
|
+
assert.doesNotThrow(() => {
|
471
|
+
utils.validateSchema(schema.getSongAdditionResponse(), json);
|
472
|
+
});
|
468
473
|
});
|
469
474
|
});
|
470
475
|
});
|
471
|
-
}
|
476
|
+
}
|