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.
Files changed (74) hide show
  1. package/.eslintrc +10 -2
  2. package/.github/workflows/build.yml +3 -3
  3. package/.github/workflows/publish.yml +3 -3
  4. package/README.md +55 -59
  5. package/bin/actions.js +28 -28
  6. package/bin/index.js +4 -4
  7. package/bin/runner.js +1 -1
  8. package/bin/utils.js +6 -2
  9. package/dist/client/museria.client.js +7 -7
  10. package/dist/face/45a265d0f07b31cde85f.ttf +0 -0
  11. package/dist/face/6205fd00fb1b573e9f0f.ttf +0 -0
  12. package/dist/face/8d3cabfc66809162fb4d.woff2 +0 -0
  13. package/dist/face/fb8184add5a3101ad0a3.woff2 +0 -0
  14. package/dist/face/museria.face.js +33 -13
  15. package/dist/face/style.css +13 -11
  16. package/package.json +41 -40
  17. package/src/browser/client/index.js +2 -1
  18. package/src/browser/face/client.js +2 -1
  19. package/src/browser/face/controllers/app/app.html +77 -69
  20. package/src/browser/face/controllers/app/app.js +14 -7
  21. package/src/browser/face/controllers/app/app.scss +2 -22
  22. package/src/browser/face/index.js +3 -3
  23. package/src/browser/face/styles/main.scss +91 -11
  24. package/src/browser/face/styles/vars.scss +0 -1
  25. package/src/client.js +73 -74
  26. package/src/collection/transports/music/index.js +20 -18
  27. package/src/db/transports/database/index.js +7 -5
  28. package/src/db/transports/loki/index.js +30 -25
  29. package/src/errors.js +2 -1
  30. package/src/index.js +8 -6
  31. package/src/node.js +312 -323
  32. package/src/schema.js +27 -29
  33. package/src/server/transports/express/api/butler/controllers.js +7 -10
  34. package/src/server/transports/express/api/butler/routes.js +5 -5
  35. package/src/server/transports/express/api/master/controllers.js +7 -10
  36. package/src/server/transports/express/api/master/routes.js +5 -5
  37. package/src/server/transports/express/api/node/controllers.js +52 -61
  38. package/src/server/transports/express/api/node/routes.js +10 -10
  39. package/src/server/transports/express/api/routes.js +1 -1
  40. package/src/server/transports/express/api/slave/controllers.js +7 -10
  41. package/src/server/transports/express/api/slave/routes.js +6 -6
  42. package/src/server/transports/express/client/controllers.js +40 -61
  43. package/src/server/transports/express/client/routes.js +33 -39
  44. package/src/server/transports/express/controllers.js +10 -21
  45. package/src/server/transports/express/index.js +23 -20
  46. package/src/server/transports/express/midds.js +67 -67
  47. package/src/server/transports/express/routes.js +12 -12
  48. package/src/utils.js +175 -184
  49. package/test/client.js +311 -305
  50. package/test/db/database.js +32 -28
  51. package/test/db/loki.js +78 -74
  52. package/test/group.js +161 -156
  53. package/test/index.js +20 -10
  54. package/test/node.js +461 -460
  55. package/test/routes.js +404 -399
  56. package/test/server/express.js +35 -31
  57. package/test/services.js +25 -18
  58. package/test/tools.js +8 -6
  59. package/test/utils.js +236 -234
  60. package/webpack.client.js +9 -7
  61. package/webpack.face.js +8 -6
  62. package/dist/face/fa-brands-400.eot +0 -0
  63. package/dist/face/fa-brands-400.svg +0 -3717
  64. package/dist/face/fa-brands-400.ttf +0 -0
  65. package/dist/face/fa-brands-400.woff +0 -0
  66. package/dist/face/fa-brands-400.woff2 +0 -0
  67. package/dist/face/fa-solid-900.eot +0 -0
  68. package/dist/face/fa-solid-900.svg +0 -5034
  69. package/dist/face/fa-solid-900.ttf +0 -0
  70. package/dist/face/fa-solid-900.woff +0 -0
  71. package/dist/face/fa-solid-900.woff2 +0 -0
  72. /package/dist/face/{open-sans.ttf → 17e98b9e5586529b13cc.ttf} +0 -0
  73. /package/dist/face/{proxima-nova.ttf → 326601dfabd91e3f016c.ttf} +0 -0
  74. /package/dist/face/{logo.svg → ee9c6af64aa224827cec.svg} +0 -0
package/test/node.js CHANGED
@@ -1,471 +1,472 @@
1
- const assert = require('chai').assert;
2
- const sharp = require('sharp');
3
- const path = require('path');
4
- const url = require('url');
5
- const Node = require('../src/node')();
6
- const utils = require('../src/utils');
7
- const tools = require('./tools');
8
-
9
- describe('Node', () => {
10
- let node;
11
-
12
- describe('instance creation', () => {
13
- it('should create an instance', async () => {
14
- const options = await tools.createNodeOptions();
15
- assert.doesNotThrow(() => node = new Node(options));
16
- });
17
- });
18
-
19
- describe('.init()', () => {
20
- it('should not throw an exception', async () => {
21
- await node.init();
22
- });
23
- });
24
-
25
- describe('.addSong()', () => {
26
- it('should throw an error because of a wrong title', async () => {
27
- try {
28
- await node.addSong(path.join(tools.tmpPath, 'audio.mp3'));
29
- throw new Error('Fail');
30
- }
31
- catch (err) {
32
- assert.isOk(err.message.match('Wrong song title'));
33
- }
34
- });
35
-
36
- it('should throw a confirmation error', async () => {
37
- const file = path.join(tools.tmpPath, 'audio.mp3');
38
- const title = 'artist - title';
39
- await utils.setSongTags(file, { fullTitle: title });
1
+ import { assert } from "chai";
2
+ import sharp from "sharp";
3
+ import path from "path";
4
+ import url from "url";
5
+ import node from "../src/node.js";
6
+ import utils from "../src/utils.js";
7
+ import tools from "./tools.js";
8
+
9
+ const Node = node();
10
+
11
+ export default function () {
12
+ describe('Node', () => {
13
+ let node;
14
+
15
+ describe('instance creation', () => {
16
+ it('should create an instance', async () => {
17
+ const options = await tools.createNodeOptions();
18
+ assert.doesNotThrow(() => node = new Node(options));
19
+ });
20
+ });
21
+
22
+ describe('.init()', () => {
23
+ it('should not throw an exception', async () => {
24
+ await node.init();
25
+ });
26
+ });
27
+
28
+ describe('.addSong()', () => {
29
+ it('should throw an error because of a wrong title', async () => {
30
+ try {
31
+ await node.addSong(path.join(tools.tmpPath, 'audio.mp3'));
32
+ throw new Error('Fail');
33
+ }
34
+ catch (err) {
35
+ assert.isOk(err.message.match('Wrong song title'));
36
+ }
37
+ });
38
+
39
+ it('should throw a confirmation error', async () => {
40
+ const file = path.join(tools.tmpPath, 'audio.mp3');
41
+ const title = 'artist - title';
42
+ await utils.setSongTags(file, { fullTitle: title });
43
+
44
+ try {
45
+ await node.addSong(file, { priority: 1, controlled: true });
46
+ throw new Error('Fail');
47
+ }
48
+ catch (err) {
49
+ assert.isOk(err.message.match('requires confirmation'));
50
+ }
51
+ });
52
+
53
+ it('should add the song', async () => {
54
+ const file = path.join(tools.tmpPath, 'audio.mp3');
55
+ const title = 'artist - title';
56
+ await utils.setSongTags(file, { fullTitle: title, TIT3: 'x' });
57
+ const result = await node.addSong(file);
58
+ const doc = await node.db.getMusicByPk(result.title);
59
+ assert.equal(utils.beautifySongTitle(title), result.title, 'check the title');
60
+ assert.equal(utils.prepareComparisonSongTitle(title), doc.compTitle, 'check the compTitle');
61
+ assert.equal(result.tags.TIT3, 'x', 'check the tags');
62
+ assert.isNotNull(doc, 'check the database');
63
+ assert.isTrue(await node.hasFile(doc.fileHash), 'check the file');
64
+ assert.isTrue(utils.isValidSongAudioLink(result.audioLink), 'check the audio link');
65
+ assert.isTrue(result.coverLink == '', 'check the cover link');
66
+ });
67
+
68
+ it('should not replace the current song with the similar one', async () => {
69
+ let file = path.join(tools.tmpPath, 'audio.mp3');
70
+ const title = 'artists - title';
71
+ file = await utils.setSongTags(file, { fullTitle: title, TIT3: 'y', TALB: 'z' });
72
+ const result = await node.addSong(file);
73
+ const docs = await node.db.getDocuments('music');
74
+ assert.lengthOf(docs, 1, 'check the docs');
75
+ assert.notEqual(utils.beautifySongTitle(title), result.title, 'check the title');
76
+ assert.isOk(result.tags.TIT3 == 'x' && result.tags.TALB == 'z', 'check the tags');
77
+ assert.isFalse(await node.hasFile(await utils.getFileHash(file)), 'check the file');
78
+ });
79
+
80
+ it('should replace the current song with the similar one', async () => {
81
+ const rel = node.options.music.relevanceTime;
82
+ node.options.music.relevanceTime = 1;
83
+ let file = path.join(tools.tmpPath, 'audio.mp3');
84
+ const title = 'artist - title';
85
+ file = await utils.setSongTags(file, { fullTitle: title, TIT3: 'y' });
86
+ const oldDoc = Object.assign({}, await node.db.getMusicByPk(title));
87
+ const result = await node.addSong(file);
88
+ const newDoc = await node.db.getMusicByPk(title);
89
+ const docs = await node.db.getDocuments('music');
90
+ const tags = utils.createSongTags(result.tags);
91
+ assert.lengthOf(docs, 1, 'check the docs');
92
+ assert.equal(utils.beautifySongTitle(title), tags.fullTitle, 'check the title');
93
+ assert.equal(result.tags.TIT3, 'y', 'check the tags');
94
+ assert.isTrue(await node.hasFile(newDoc.fileHash), 'check the new file');
95
+ assert.isFalse(await node.hasFile(oldDoc.fileHash), 'check the old file');
96
+ node.options.music.relevanceTime = rel;
97
+ });
98
+
99
+ it('should add the song with a cover', async () => {
100
+ const file = path.join(tools.tmpPath, 'audio.mp3');
101
+ const title = 'new - song';
102
+ await utils.setSongTags(file, { fullTitle: title, APIC: path.join(tools.tmpPath, 'cover.jpg') });
103
+ const result = await node.addSong(file);
104
+ const doc = await node.db.getMusicByPk(result.title);
105
+ const docs = await node.db.getDocuments('music');
106
+ assert.equal(utils.beautifySongTitle(title), result.title, 'check the title');
107
+ assert.isNotNull(doc, 'check the doc');
108
+ assert.lengthOf(docs, 2, 'check the database');
109
+ assert.isTrue(utils.isValidSongCoverLink(result.coverLink), 'check the audio link');
110
+ });
111
+ });
112
+
113
+ describe('.getSongInfo()', () => {
114
+ it('should return an empty array with a wrong title', async () => {
115
+ const title = 'unexistent';
116
+ const result = await node.getSongInfo(title);
117
+ assert.lengthOf(result, 0);
118
+ });
119
+
120
+ it('should return an empty array with a right title', async () => {
121
+ const title = 'unexistent - unexistent';
122
+ const result = await node.getSongInfo(title);
123
+ assert.lengthOf(result, 0);
124
+ });
125
+
126
+ it('should return the appropriate song', async () => {
127
+ const title = 'news - song';
128
+ const similarity = node.options.music.similarity;
129
+ const result = await node.getSongInfo(title);
130
+ const doc = await node.db.getMusicByPk(title);
131
+ const tags = utils.createSongTags(result[0].tags);
132
+ assert.lengthOf(result, 1, 'check the array');
133
+ assert.isTrue(utils.getSongSimilarity(doc.title, result[0].title) >= similarity, 'check the title');
134
+ assert.equal(tags.fullTitle, doc.title, 'check the tags');
135
+ assert.isTrue(utils.isValidSongAudioLink(result[0].audioLink), 'check the audio link');
136
+ assert.isTrue(utils.isValidSongCoverLink(result[0].coverLink), 'check the cover link');
137
+ });
138
+ });
139
+
140
+ describe('.getSongAudioLink()', () => {
141
+ it('should throw an error', async () => {
142
+ try {
143
+ await node.getSongAudioLink('unexistent song');
144
+ throw new Error('Fail');
145
+ }
146
+ catch (err) {
147
+ assert.isOk(err.message.match('Wrong song title'));
148
+ }
149
+ });
150
+
151
+ it('should return an empty string', async () => {
152
+ const result = await node.getSongAudioLink('unexistent - unexistent');
153
+ assert.equal(result, '');
154
+ });
155
+
156
+ it('should return the appropriate song link', async () => {
157
+ const result = await node.getSongAudioLink('new - song');
158
+ assert.isTrue(utils.isValidSongAudioLink(result));
159
+ });
160
+ });
161
+
162
+ describe('.getSongCoverLink()', () => {
163
+ it('should throw an error', async () => {
164
+ try {
165
+ await node.getSongCoverLink('unexistent song');
166
+ throw new Error('Fail');
167
+ }
168
+ catch (err) {
169
+ assert.isOk(err.message.match('Wrong song title'));
170
+ }
171
+ });
172
+
173
+ it('should return an empty string', async () => {
174
+ const result = await node.getSongCoverLink('unexistent - unexistent');
175
+ assert.equal(result, '');
176
+ });
177
+
178
+ it('should return the appropriate song link', async () => {
179
+ const result = await node.getSongCoverLink('new - song');
180
+ assert.isTrue(utils.isValidSongCoverLink(result));
181
+ });
182
+ });
183
+
184
+ describe('.removeSong()', () => {
185
+ it('should remove the song', async () => {
186
+ const title = 'artists - title';
187
+ const doc = await node.db.getMusicByPk(title);
188
+ const res = await node.removeSong(title);
189
+ assert.equal(res.removed, 1, 'check the result');
190
+ assert.isNull(await node.db.getMusicByPk(title), 'check the database');
191
+ assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
192
+ });
193
+ });
194
+
195
+ describe('.updateSongCache()', () => {
196
+ let title;
197
+
198
+ before(async () => {
199
+ title = 'new - song';
200
+ });
201
+
202
+ it('should not add the cache because of a wrong link', async () => {
203
+ const value = {
204
+ audioLink: 'wrong'
205
+ };
206
+ await node.updateSongCache(title, value);
207
+ assert.isNull(await node.cacheFile.get(title));
208
+ });
209
+
210
+ it('should add the cache partially', async () => {
211
+ const doc = await node.db.getMusicByPk(title);
212
+ const info = url.parse(await node.createSongAudioLink(doc));
213
+ const audioLink = url.format(Object.assign(info, { host: 'example.com:80' }));
214
+ const value = {
215
+ audioLink,
216
+ coverLink: 'wrong'
217
+ };
218
+ await node.updateSongCache(title, value);
219
+ const cache = (await node.cacheFile.get(title)).value;
220
+ assert.equal(audioLink, cache.audioLink, 'check the audio');
221
+ assert.isNotOk(cache.coverLink, 'check the cover');
222
+ });
223
+
224
+ it('should add the cache completely', async () => {
225
+ const doc = await node.db.getMusicByPk(title);
226
+ let info = url.parse(await node.createSongAudioLink(doc));
227
+ const audioLink = url.format(Object.assign(info, { host: 'example.com:80' }));
228
+ info = url.parse(await node.createSongCoverLink(doc));
229
+ const coverLink = url.format(Object.assign(info, { host: 'example.com:80' }));
230
+ const value = {
231
+ audioLink,
232
+ coverLink,
233
+ userless: true
234
+ };
235
+ await node.updateSongCache(title, value);
236
+ const cache = (await node.cacheFile.get(title)).value;
237
+ assert.equal(audioLink, cache.audioLink, 'check the audio');
238
+ assert.equal(coverLink, cache.coverLink, 'check the cover');
239
+ assert.isUndefined(cache.userless, 'check the wrong proprty');
240
+ });
241
+ });
242
+
243
+ describe('.createSongAudioLink()', () => {
244
+ it('should create a right audio link', async () => {
245
+ const doc = await node.db.getMusicByPk('new - song');
246
+ const code = utils.encodeSongTitle(doc.title);
247
+ const hash = doc.fileHash;
248
+ assert.equal(await node.createSongAudioLink(doc), `http://${node.address}/audio/${code}.mp3?f=${hash}`);
249
+ });
250
+ });
251
+
252
+ describe('.createSongCoverLink()', () => {
253
+ it('should create a right cover link', async () => {
254
+ const doc = await node.db.getMusicByPk('new - song');
255
+ const hash = doc.fileHash;
256
+ const code = utils.encodeSongTitle(doc.title);
257
+ assert.equal(await node.createSongCoverLink(doc), `http://${node.address}/cover/${code}.jpeg?f=${hash}`);
258
+ });
259
+ });
260
+
261
+ describe('.checkSongRelevance()', () => {
262
+ let title;
263
+ before(() => {
264
+ title = 'new - song';
265
+ });
266
+ it('should return true', async () => {
267
+ const doc = await node.db.getMusicByPk(title);
268
+ const filePath = node.getFilePath(doc.fileHash);
269
+ assert.isTrue(await node.checkSongRelevance(filePath, filePath));
270
+ });
271
+ });
272
+
273
+ describe('.removeFileFromStorage()', () => {
274
+ let title;
40
275
 
41
- try {
42
- await node.addSong(file, { priority: 1, controlled: true });
43
- throw new Error('Fail');
44
- }
45
- catch(err) {
46
- assert.isOk(err.message.match('requires confirmation'))
47
- }
48
- });
49
-
50
- it('should add the song', async () => {
51
- const file = path.join(tools.tmpPath, 'audio.mp3');
52
- const title = 'artist - title' ;
53
- await utils.setSongTags(file, { fullTitle: title, TIT3: 'x' });
54
- const result = await node.addSong(file);
55
- const doc = await node.db.getMusicByPk(result.title);
56
- assert.equal(utils.beautifySongTitle(title), result.title, 'check the title');
57
- assert.equal(utils.prepareComparisonSongTitle(title), doc.compTitle, 'check the compTitle');
58
- assert.equal(result.tags.TIT3, 'x', 'check the tags');
59
- assert.isNotNull(doc, 'check the database');
60
- assert.isTrue(await node.hasFile(doc.fileHash), 'check the file');
61
- assert.isTrue(utils.isValidSongAudioLink(result.audioLink), 'check the audio link');
62
- assert.isTrue(result.coverLink == '', 'check the cover link');
63
- });
64
-
65
- it('should not replace the current song with the similar one', async () => {
66
- let file = path.join(tools.tmpPath, 'audio.mp3');
67
- const title = 'artists - title' ;
68
- file = await utils.setSongTags(file, { fullTitle: title, TIT3: 'y', TALB: 'z' });
69
- const result = await node.addSong(file);
70
- const docs = await node.db.getDocuments('music');
71
- assert.lengthOf(docs, 1, 'check the docs');
72
- assert.notEqual(utils.beautifySongTitle(title), result.title, 'check the title');
73
- assert.isOk(result.tags.TIT3 == 'x' && result.tags.TALB == 'z', 'check the tags');
74
- assert.isFalse(await node.hasFile(await utils.getFileHash(file)), 'check the file');
75
- });
76
-
77
- it('should replace the current song with the similar one', async () => {
78
- const rel = node.options.music.relevanceTime;
79
- node.options.music.relevanceTime = 1;
80
- let file = path.join(tools.tmpPath, 'audio.mp3');
81
- const title = 'artist - title' ;
82
- file = await utils.setSongTags(file, { fullTitle: title, TIT3: 'y'});
83
- const oldDoc = Object.assign({}, await node.db.getMusicByPk(title));
84
- const result = await node.addSong(file);
85
- const newDoc = await node.db.getMusicByPk(title);
86
- const docs = await node.db.getDocuments('music');
87
- const tags = utils.createSongTags(result.tags);
88
- assert.lengthOf(docs, 1, 'check the docs');
89
- assert.equal(utils.beautifySongTitle(title), tags.fullTitle, 'check the title');
90
- assert.equal(result.tags.TIT3, 'y', 'check the tags');
91
- assert.isTrue(await node.hasFile(newDoc.fileHash), 'check the new file');
92
- assert.isFalse(await node.hasFile(oldDoc.fileHash), 'check the old file');
93
- node.options.music.relevanceTime = rel;
94
- });
95
-
96
- it('should add the song with a cover', async () => {
97
- const file = path.join(tools.tmpPath, 'audio.mp3');
98
- const title = 'new - song';
99
- await utils.setSongTags(file, { fullTitle: title, APIC: path.join(tools.tmpPath, 'cover.jpg') });
100
- const result = await node.addSong(file);
101
- const doc = await node.db.getMusicByPk(result.title);
102
- const docs = await node.db.getDocuments('music');
103
- assert.equal(utils.beautifySongTitle(title), result.title, 'check the title');
104
- assert.isNotNull(doc, 'check the doc');
105
- assert.lengthOf(docs, 2, 'check the database');
106
- assert.isTrue(utils.isValidSongCoverLink(result.coverLink), 'check the audio link');
107
- });
108
- });
109
-
110
- describe('.getSongInfo()', () => {
111
- it('should return an empty array with a wrong title', async () => {
112
- const title = 'unexistent';
113
- const result = await node.getSongInfo(title);
114
- assert.lengthOf(result, 0);
115
- });
116
-
117
- it('should return an empty array with a right title', async () => {
118
- const title = 'unexistent - unexistent';
119
- const result = await node.getSongInfo(title);
120
- assert.lengthOf(result, 0);
121
- });
122
-
123
- it('should return the appropriate song', async () => {
124
- const title = 'news - song';
125
- const similarity = node.options.music.similarity;
126
- const result = await node.getSongInfo(title);
127
- const doc = await node.db.getMusicByPk(title);
128
- const tags = utils.createSongTags(result[0].tags);
129
- assert.lengthOf(result, 1, 'check the array');
130
- assert.isTrue(utils.getSongSimilarity(doc.title, result[0].title) >= similarity, 'check the title');
131
- assert.equal(tags.fullTitle, doc.title, 'check the tags');
132
- assert.isTrue(utils.isValidSongAudioLink(result[0].audioLink), 'check the audio link');
133
- assert.isTrue(utils.isValidSongCoverLink(result[0].coverLink), 'check the cover link');
134
- });
135
- });
136
-
137
- describe('.getSongAudioLink()', () => {
138
- it('should throw an error', async () => {
139
- try {
140
- await node.getSongAudioLink('unexistent song');
141
- throw new Error('Fail');
142
- }
143
- catch (err) {
144
- assert.isOk(err.message.match('Wrong song title'));
145
- }
146
- });
147
-
148
- it('should return an empty string', async () => {
149
- const result = await node.getSongAudioLink('unexistent - unexistent');
150
- assert.equal(result, '');
151
- });
152
-
153
- it('should return the appropriate song link', async () => {
154
- const result = await node.getSongAudioLink('new - song');
155
- assert.isTrue(utils.isValidSongAudioLink(result));
156
- });
157
- });
158
-
159
- describe('.getSongCoverLink()', () => {
160
- it('should throw an error', async () => {
161
- try {
162
- await node.getSongCoverLink('unexistent song');
163
- throw new Error('Fail');
164
- }
165
- catch (err) {
166
- assert.isOk(err.message.match('Wrong song title'));
167
- }
168
- });
169
-
170
- it('should return an empty string', async () => {
171
- const result = await node.getSongCoverLink('unexistent - unexistent');
172
- assert.equal(result, '');
173
- });
174
-
175
- it('should return the appropriate song link', async () => {
176
- const result = await node.getSongCoverLink('new - song');
177
- assert.isTrue(utils.isValidSongCoverLink(result));
178
- });
179
- });
180
-
181
- describe('.removeSong()', () => {
182
- it('should remove the song', async () => {
183
- const title = 'artists - title';
184
- const doc = await node.db.getMusicByPk(title)
185
- const res = await node.removeSong(title);
186
- assert.equal(res.removed, 1, 'check the result');
187
- assert.isNull(await node.db.getMusicByPk(title), 'check the database');
188
- assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
189
- });
190
- });
191
-
192
- describe('.updateSongCache()', () => {
193
- let title;
194
-
195
- before(async () => {
196
- title = 'new - song';
197
- });
198
-
199
- it('should not add the cache because of a wrong link', async () => {
200
- const value = {
201
- audioLink: 'wrong'
202
- };
203
- await node.updateSongCache(title, value);
204
- assert.isNull(await node.cacheFile.get(title));
205
- });
206
-
207
- it('should add the cache partially', async () => {
208
- const doc = await node.db.getMusicByPk(title);
209
- const info = url.parse(await node.createSongAudioLink(doc));
210
- const audioLink = url.format(Object.assign(info, { host: 'example.com:80' }));
211
- const value = {
212
- audioLink,
213
- coverLink: 'wrong'
214
- };
215
- await node.updateSongCache(title, value);
216
- const cache = (await node.cacheFile.get(title)).value;
217
- assert.equal(audioLink, cache.audioLink, 'check the audio');
218
- assert.isNotOk(cache.coverLink, 'check the cover');
219
- });
220
-
221
- it('should add the cache completely', async () => {
222
- const doc = await node.db.getMusicByPk(title);
223
- let info = url.parse(await node.createSongAudioLink(doc));
224
- const audioLink = url.format(Object.assign(info, { host: 'example.com:80' }));
225
- info = url.parse(await node.createSongCoverLink(doc));
226
- const coverLink = url.format(Object.assign(info, { host: 'example.com:80' }));
227
- const value = {
228
- audioLink,
229
- coverLink,
230
- userless: true
231
- };
232
- await node.updateSongCache(title, value);
233
- const cache = (await node.cacheFile.get(title)).value;
234
- assert.equal(audioLink, cache.audioLink, 'check the audio');
235
- assert.equal(coverLink, cache.coverLink, 'check the cover');
236
- assert.isUndefined(cache.userless, 'check the wrong proprty');
237
- });
238
- });
239
-
240
- describe('.createSongAudioLink()', () => {
241
- it('should create a right audio link', async () => {
242
- const doc = await node.db.getMusicByPk('new - song');
243
- const code = utils.encodeSongTitle(doc.title);
244
- const hash = doc.fileHash;
245
- assert.equal(await node.createSongAudioLink(doc), `http://${node.address}/audio/${code}.mp3?f=${hash}`);
246
- });
247
- });
248
-
249
- describe('.createSongCoverLink()', () => {
250
- it('should create a right cover link', async () => {
251
- const doc = await node.db.getMusicByPk('new - song');
252
- const hash = doc.fileHash;
253
- const code = utils.encodeSongTitle(doc.title);
254
- assert.equal(await node.createSongCoverLink(doc), `http://${node.address}/cover/${code}.jpeg?f=${hash}`);
255
- });
256
- });
257
-
258
- describe('.checkSongRelevance()', () => {
259
- let title;
260
-
261
- before(() => {
262
- title = 'new - song';
263
- });
264
-
265
- it('should return true', async () => {
266
- const doc = await node.db.getMusicByPk(title);
267
- const filePath = node.getFilePath(doc.fileHash);
268
- assert.isTrue(await node.checkSongRelevance(filePath, filePath));
269
- });
270
- });
271
-
272
- describe('.removeFileFromStorage()', () => {
273
- let title;
274
-
275
- before(() => {
276
- title = 'new - song';
277
- });
278
-
279
- it('should remove the file and the document', async () => {
280
- const doc = await node.db.getMusicByPk(title);
281
- await node.removeFileFromStorage(doc.fileHash);
282
- assert.isNull(await node.db.getMusicByPk(title), 'check the database');
283
- assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
284
- });
285
-
286
- it('should remove the file and the document', async () => {
287
- await node.addSong(path.join(tools.tmpPath, 'audio.mp3'));
288
- const doc = await node.db.getMusicByPk(title);
289
- assert.isObject(doc, 'check the database before');
290
- await node.removeFileFromStorage(doc.fileHash, { ignoreDocument: true });
291
- assert.isObject(await node.db.getMusicByPk(title));
292
- assert.isFalse(await node.hasFile(doc.fileHash));
293
- });
294
- });
295
-
296
- describe('.prepareSongCover', () => {
297
- it('should throw an error because of minimum width', async () => {
298
- try {
299
- const image = sharp(path.join(tools.tmpPath, 'cover.jpg'));
300
- const metadata = await image.metadata();
301
- image.resize(node.options.music.coverMinSize - 1, metadata.height);
302
- await node.prepareSongCover(await image.toBuffer());
303
- throw new Error('Fail');
304
- }
305
- catch (err) {
306
- assert.isOk(err.message.match('Minimum size'));
307
- }
308
- });
309
-
310
- it('should throw an error because of minimum height', async () => {
311
- try {
312
- const image = sharp(path.join(tools.tmpPath, 'cover.jpg'));
276
+ before(() => {
277
+ title = 'new - song';
278
+ });
279
+
280
+ it('should remove the file and the document', async () => {
281
+ const doc = await node.db.getMusicByPk(title);
282
+ await node.removeFileFromStorage(doc.fileHash);
283
+ assert.isNull(await node.db.getMusicByPk(title), 'check the database');
284
+ assert.isFalse(await node.hasFile(doc.fileHash), 'check the file');
285
+ });
286
+
287
+ it('should remove the file and the document', async () => {
288
+ await node.addSong(path.join(tools.tmpPath, 'audio.mp3'));
289
+ const doc = await node.db.getMusicByPk(title);
290
+ assert.isObject(doc, 'check the database before');
291
+ await node.removeFileFromStorage(doc.fileHash, { ignoreDocument: true });
292
+ assert.isObject(await node.db.getMusicByPk(title));
293
+ assert.isFalse(await node.hasFile(doc.fileHash));
294
+ });
295
+ });
296
+
297
+ describe('.prepareSongCover', () => {
298
+ it('should throw an error because of minimum width', async () => {
299
+ try {
300
+ const image = sharp(path.join(tools.tmpPath, 'cover.jpg'));
301
+ const metadata = await image.metadata();
302
+ image.resize(node.options.music.coverMinSize - 1, metadata.height);
303
+ await node.prepareSongCover(await image.toBuffer());
304
+ throw new Error('Fail');
305
+ }
306
+ catch (err) {
307
+ assert.isOk(err.message.match('Minimum size'));
308
+ }
309
+ });
310
+
311
+ it('should throw an error because of minimum height', async () => {
312
+ try {
313
+ const image = sharp(path.join(tools.tmpPath, 'cover.jpg'));
314
+ const metadata = await image.metadata();
315
+ image.resize(metadata.width, node.options.music.coverMinSize - 1);
316
+ await node.prepareSongCover(await image.toBuffer());
317
+ throw new Error('Fail');
318
+ }
319
+ catch (err) {
320
+ assert.isOk(err.message.match('Minimum size'));
321
+ }
322
+ });
323
+
324
+ it('should prepare and resize the image', async () => {
325
+ const maxSize = node.options.music.coverMaxSize;
326
+ const buffer = await node.prepareSongCover(path.join(tools.tmpPath, 'cover.jpg'));
327
+ const image = sharp(buffer);
313
328
  const metadata = await image.metadata();
314
- image.resize(metadata.width, node.options.music.coverMinSize - 1);
315
- await node.prepareSongCover(await image.toBuffer());
316
- throw new Error('Fail');
317
- }
318
- catch (err) {
319
- assert.isOk(err.message.match('Minimum size'));
320
- }
329
+ assert.instanceOf(buffer, Buffer);
330
+ assert.isTrue(metadata.width <= maxSize && metadata.height <= maxSize);
331
+ });
321
332
  });
322
333
 
323
- it('should prepare and resize the image', async () => {
324
- const maxSize = node.options.music.coverMaxSize;
325
- const buffer = await node.prepareSongCover(path.join(tools.tmpPath, 'cover.jpg'));
326
- const image = sharp(buffer);
327
- const metadata = await image.metadata();
328
- assert.instanceOf(buffer, Buffer);
329
- assert.isTrue(metadata.width <= maxSize && metadata.height <= maxSize);
334
+ describe('.prepareSongTitle()', () => {
335
+ it('should return beautified title', async () => {
336
+ const title = 'artist - song ft. artist2';
337
+ const res = await node.prepareSongTitle(title);
338
+ assert.equal(res, utils.beautifySongTitle(title));
339
+ });
330
340
  });
331
- });
332
341
 
333
- describe('.prepareSongTitle()', () => {
334
- it('should return beautified title', async () => {
335
- const title = 'artist - song ft. artist2';
336
- const res = await node.prepareSongTitle(title);
337
- assert.equal(res, utils.beautifySongTitle(title));
338
- });
339
- });
340
-
341
- describe('.cleanUpMusic()', () => {
342
- it('should remove wrong documents', async () => {
343
- const title = 'test - test';
344
- await node.db.addMusicDocument({ title });
345
- await node.cleanUpMusic();
346
- assert.isNull(await node.db.getDocumentByPk('music', title))
347
- });
348
-
349
- it('should not remove wrong files', async () => {
350
- const filePath = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle: 'another - song' });
351
- const hash = await utils.getFileHash(filePath);
352
- await node.withAddingFile(hash, async () => {
353
- await node.addFileToStorage(filePath, hash, { copy: true });
342
+ describe('.cleanUpMusic()', () => {
343
+ it('should remove wrong documents', async () => {
344
+ const title = 'test - test';
345
+ await node.db.addMusicDocument({ title });
354
346
  await node.cleanUpMusic();
355
- });
356
- assert.isTrue(await node.hasFile(hash));
357
- });
358
-
359
- it('should remove wrong files', async () => {
360
- const hash = await utils.getFileHash(path.join(tools.tmpPath, 'audio.mp3'));
361
- await node.cleanUpMusic();
362
- assert.isFalse(await node.hasFile(hash));
363
- });
364
- });
365
-
366
- describe('.normalizeSongTitles()', () => {
367
- it('should beautify song titles', async () => {
368
- const title = 'ARTIST - test';
369
- await node.db.addMusicDocument({ title });
370
- await node.normalizeSongTitles();
371
- const beauty = utils.beautifySongTitle(title);
372
- const docs = await node.db.getDocuments('music');
373
- assert.notEqual(title, beauty, 'check the title');
374
- assert.equal(docs[docs.length - 1].compTitle, utils.prepareComparisonSongTitle(beauty), 'check the doc');
347
+ assert.isNull(await node.db.getDocumentByPk('music', title));
348
+ });
349
+
350
+ it('should not remove wrong files', async () => {
351
+ const filePath = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle: 'another - song' });
352
+ const hash = await utils.getFileHash(filePath);
353
+ await node.withAddingFile(hash, async () => {
354
+ await node.addFileToStorage(filePath, hash, { copy: true });
355
+ await node.cleanUpMusic();
356
+ });
357
+ assert.isTrue(await node.hasFile(hash));
358
+ });
359
+
360
+ it('should remove wrong files', async () => {
361
+ const hash = await utils.getFileHash(path.join(tools.tmpPath, 'audio.mp3'));
362
+ await node.cleanUpMusic();
363
+ assert.isFalse(await node.hasFile(hash));
364
+ });
365
+ });
366
+
367
+ describe('.normalizeSongTitles()', () => {
368
+ it('should beautify song titles', async () => {
369
+ const title = 'ARTIST - test';
370
+ await node.db.addMusicDocument({ title });
371
+ await node.normalizeSongTitles();
372
+ const beauty = utils.beautifySongTitle(title);
373
+ const docs = await node.db.getDocuments('music');
374
+ assert.notEqual(title, beauty, 'check the title');
375
+ assert.equal(docs[docs.length - 1].compTitle, utils.prepareComparisonSongTitle(beauty), 'check the doc');
376
+ });
377
+ });
378
+
379
+ describe('.getStorageCleaningUpTree()', () => {
380
+ it('should get right order of priority', async () => {
381
+ for (let i = 0; i < 3; i++) {
382
+ const title = `artist${Math.random()} - title${Math.random()}`;
383
+ const filePath = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle: title });
384
+ const hash = await utils.getFileHash(filePath);
385
+ await node.db.addMusicDocument({ title, priority: 1 - i, fileHash: hash });
386
+ await node.addFileToStorage(filePath, hash, { copy: true });
387
+ }
388
+
389
+ const delay = node.__songSyncDelay;
390
+ node.__songSyncDelay = 0;
391
+ const tree = await node.getStorageCleaningUpTree();
392
+ const keys = tree.keys();
393
+ assert.isTrue(keys[0].priority == -1 && keys[1].priority == 0 && keys[2].priority == 1);
394
+ node.__songSyncDelay = delay;
395
+ });
396
+ });
397
+
398
+ describe('.exportSongs()', () => {
399
+ let importNode;
400
+
401
+ before(async () => {
402
+ importNode = new Node(await tools.createNodeOptions());
403
+ await importNode.init();
404
+ });
405
+
406
+ after(async () => {
407
+ await importNode.deinit();
408
+ });
409
+
410
+ it('should export the song', async () => {
411
+ importNode.options.network.trustlist = [node.address];
412
+ const title = 'export - song';
413
+ const filePath = path.join(tools.tmpPath, 'audio.mp3');
414
+ const file = await utils.setSongTags(filePath, { fullTitle: title });
415
+ await node.addSong(file);
416
+ await node.db.updateMusicDocument(Object.assign(await node.db.getMusicByPk(title), { priority: 1 }));
417
+ await node.exportSongs(importNode.address);
418
+ const doc = await importNode.db.getMusicByPk(title);
419
+ assert.isNotNull(doc, 'check the database');
420
+ assert.isTrue(await importNode.hasFile(doc.fileHash), 'check the file');
421
+ });
422
+ });
423
+
424
+ describe('.songTitleTest()', () => {
425
+ it('should throw an error', () => {
426
+ try {
427
+ node.songTitleTest('wrong song title');
428
+ throw new Error('Fail');
429
+ }
430
+ catch (err) {
431
+ assert.isOk(err.message.match('Wrong song'));
432
+ }
433
+ });
434
+
435
+ it('should not throw an error', async () => {
436
+ node.songTitleTest('artist - title');
437
+ });
438
+ });
439
+
440
+ describe('.uniqDocuments()', () => {
441
+ it('should remove the duplicates', async () => {
442
+ const arr = [
443
+ { fileHash: 'a' },
444
+ { fileHash: 'a' },
445
+ { fileHash: 'b' },
446
+ { fileHash: 'b' },
447
+ { fileHash: 'c' }
448
+ ];
449
+ const collection = await node.getCollection('music');
450
+ assert.lengthOf(await node.uniqDocuments(collection, arr), 3);
451
+ });
452
+ });
453
+
454
+ describe('.deinit()', () => {
455
+ it('should not throw an exception', async () => {
456
+ await node.deinit();
457
+ });
458
+ });
459
+
460
+ describe('reinitialization', () => {
461
+ it('should not throw an exception', async () => {
462
+ await node.init();
463
+ });
375
464
  });
376
- });
377
-
378
- describe('.getStorageCleaningUpTree()', () => {
379
- it('should get right order of priority', async () => {
380
- for(let i = 0; i < 3; i++) {
381
- const title = `artist${ Math.random() } - title${ Math.random() }`;
382
- const filePath = await utils.setSongTags(path.join(tools.tmpPath, 'audio.mp3'), { fullTitle: title });
383
- const hash = await utils.getFileHash(filePath);
384
- await node.db.addMusicDocument({ title, priority: 1 - i, fileHash: hash });
385
- await node.addFileToStorage(filePath, hash, { copy: true });
386
- }
387
465
 
388
- const delay = node.__songSyncDelay;
389
- this.__songSyncDelay = 0;
390
- const tree = await node.getStorageCleaningUpTree();
391
- const keys = tree.keys();
392
- assert.isTrue(keys[0].priority == -1 && keys[1].priority == 0 && keys[2].priority == 1);
393
- node.__songSyncDelay = delay;
394
- });
395
- });
396
-
397
- describe('.exportSongs()', () => {
398
- let importNode;
399
-
400
- before(async () => {
401
- importNode = new Node(await tools.createNodeOptions());
402
- await importNode.init();
403
- });
404
-
405
- after(async () => {
406
- await importNode.deinit();
407
- });
408
-
409
- it('should export the song', async () => {
410
- importNode.options.network.trustlist = [node.address];
411
- const title = 'export - song';
412
- const filePath = path.join(tools.tmpPath, 'audio.mp3');
413
- const file = await utils.setSongTags(filePath, { fullTitle: title });
414
- await node.addSong(file);
415
- await node.db.updateMusicDocument(Object.assign(await node.db.getMusicByPk(title), { priority: 1 }));
416
- await node.exportSongs(importNode.address);
417
- const doc = await importNode.db.getMusicByPk(title);
418
- assert.isNotNull(doc, 'check the database');
419
- assert.isTrue(await importNode.hasFile(doc.fileHash), 'check the file');
420
- });
421
- });
422
-
423
- describe('.songTitleTest()', () => {
424
- it('should throw an error', () => {
425
- try {
426
- node.songTitleTest('wrong song title');
427
- throw new Error('Fail');
428
- }
429
- catch (err) {
430
- assert.isOk(err.message.match('Wrong song'));
431
- }
432
- });
433
-
434
- it('should not throw an error', async () => {
435
- node.songTitleTest('artist - title');
436
- });
437
- });
438
-
439
- describe('.uniqDocuments()', () => {
440
- it('should remove the duplicates', async () => {
441
- const arr = [
442
- { fileHash: 'a' },
443
- { fileHash: 'a' },
444
- { fileHash: 'b' },
445
- { fileHash: 'b' },
446
- { fileHash: 'c' }
447
- ];
448
-
449
- const collection = await node.getCollection('music');
450
- assert.lengthOf(await node.uniqDocuments(collection, arr), 3);
451
- });
452
- });
453
-
454
- describe('.deinit()', () => {
455
- it('should not throw an exception', async () => {
456
- await node.deinit();
457
- });
458
- });
459
-
460
- describe('reinitialization', () => {
461
- it('should not throw an exception', async () => {
462
- await node.init();
463
- });
464
- });
465
-
466
- describe('.destroy()', () => {
467
- it('should not throw an exception', async () => {
468
- await node.destroy();
466
+ describe('.destroy()', () => {
467
+ it('should not throw an exception', async () => {
468
+ await node.destroy();
469
+ });
469
470
  });
470
471
  });
471
- });
472
+ }