aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-01-23 18:31:58 +0100
committerChocobozzz <florian.bigard@gmail.com>2016-01-23 18:31:58 +0100
commit45239549bf2659998dcf9196d86974b0b625912e (patch)
tree823d324db097400a7b5ae59a03deff54c5fd86ef
parent2cc8ebf134b66047cd639ee7324e1ecfd5c5fd18 (diff)
downloadPeerTube-45239549bf2659998dcf9196d86974b0b625912e.tar.gz
PeerTube-45239549bf2659998dcf9196d86974b0b625912e.tar.zst
PeerTube-45239549bf2659998dcf9196d86974b0b625912e.zip
Finalise the join in a network and add the ability to quit it
-rw-r--r--README.md7
-rw-r--r--middlewares/misc.js9
-rw-r--r--public/javascripts/index.js40
-rw-r--r--routes/api/v1/pods.js31
-rw-r--r--routes/api/v1/remoteVideos.js2
-rw-r--r--src/pods.js152
-rw-r--r--src/poolRequests.js32
-rw-r--r--src/utils.js10
-rw-r--r--src/videos.js34
-rw-r--r--test/api/friendsAdvanced.js88
-rw-r--r--test/api/friendsBasic.js90
-rw-r--r--test/api/multiplePods.js4
-rw-r--r--test/api/utils.js28
-rw-r--r--views/panel.jade14
14 files changed, 442 insertions, 99 deletions
diff --git a/README.md b/README.md
index 1e1b1db56..cb1c3d907 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,12 @@ Thanks to [webtorrent](https://github.com/feross/webtorrent), we can make P2P (t
21- [ ] Frontend 21- [ ] Frontend
22 - [X] Simple frontend (All elements are generated by jQuery) 22 - [X] Simple frontend (All elements are generated by jQuery)
23 - [ ] AngularJS frontend 23 - [ ] AngularJS frontend
24- [ ] Join a network 24- [X] Join a network
25 - [X] Generate a RSA key 25 - [X] Generate a RSA key
26 - [X] Ask for the friend list of other pods and make friend with them 26 - [X] Ask for the friend list of other pods and make friend with them
27 - [ ] Get the list of the videos owned by a pod when making friend with it 27 - [X] Get the list of the videos owned by a pod when making friend with it
28 - [ ] Post the list of its own videos when making friend with another pod 28 - [X] Post the list of its own videos when making friend with another pod
29- [X] Quit a network
29- [X] Upload a video 30- [X] Upload a video
30 - [X] Seed the video 31 - [X] Seed the video
31 - [X] Send the meta data to all other friends 32 - [X] Send the meta data to all other friends
diff --git a/middlewares/misc.js b/middlewares/misc.js
index 9755eeff0..c10b0792a 100644
--- a/middlewares/misc.js
+++ b/middlewares/misc.js
@@ -28,7 +28,12 @@
28 PodsDB.findOne({ url: req.body.signature.url }, function (err, pod) { 28 PodsDB.findOne({ url: req.body.signature.url }, function (err, pod) {
29 if (err) { 29 if (err) {
30 logger.error('Cannot get signed url in decryptBody.', { error: err }) 30 logger.error('Cannot get signed url in decryptBody.', { error: err })
31 res.sendStatus(500) 31 return res.sendStatus(500)
32 }
33
34 if (pod === null) {
35 logger.error('Unknown pod %s.', req.body.signature.url)
36 return res.sendStatus(403)
32 } 37 }
33 38
34 logger.debug('Decrypting body from %s.', req.body.signature.url) 39 logger.debug('Decrypting body from %s.', req.body.signature.url)
@@ -43,7 +48,7 @@
43 delete req.body.key 48 delete req.body.key
44 } else { 49 } else {
45 logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url) 50 logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url)
46 res.sendStatus(500) 51 return res.sendStatus(403)
47 } 52 }
48 53
49 next() 54 next()
diff --git a/public/javascripts/index.js b/public/javascripts/index.js
index c0388c55a..5d42f02e0 100644
--- a/public/javascripts/index.js
+++ b/public/javascripts/index.js
@@ -31,6 +31,10 @@
31 makeFriends() 31 makeFriends()
32 }) 32 })
33 33
34 $('#panel_quit_friends').on('click', function () {
35 quitFriends()
36 })
37
34 $('#search-video').on('keyup', function (e) { 38 $('#search-video').on('keyup', function (e) {
35 var search = $(this).val() 39 var search = $(this).val()
36 40
@@ -60,6 +64,17 @@
60 }) 64 })
61 } 65 }
62 66
67 function quitFriends () {
68 $.ajax({
69 url: '/api/v1/pods/quitfriends',
70 type: 'GET',
71 dataType: 'json',
72 success: function () {
73 alert('Quit friends!')
74 }
75 })
76 }
77
63 function printVideos (videos) { 78 function printVideos (videos) {
64 $content.empty() 79 $content.empty()
65 80
@@ -72,8 +87,21 @@
72 87
73 var $video_name = $('<span></span>').addClass('video_name').text(video.name) 88 var $video_name = $('<span></span>').addClass('video_name').text(video.name)
74 var $video_pod = $('<span></span>').addClass('video_pod_url').text(video.podUrl) 89 var $video_pod = $('<span></span>').addClass('video_pod_url').text(video.podUrl)
75 var $remove = $('<span></span>').addClass('span_action glyphicon glyphicon-remove') 90 var $header = $('<div></div>').append([ $video_name, $video_pod ])
76 var $header = $('<div></div>').append([ $video_name, $video_pod, $remove ]) 91
92 if (video.namePath !== null) {
93 var $remove = $('<span></span>').addClass('span_action glyphicon glyphicon-remove')
94
95 // Remove the video
96 $remove.on('click', function () {
97 // TODO
98 if (!confirm('Are you sure ?')) return
99
100 removeVideo(video)
101 })
102
103 $header.append($remove)
104 }
77 105
78 var $video_description = $('<div></div>').addClass('video_description').text(video.description) 106 var $video_description = $('<div></div>').addClass('video_description').text(video.description)
79 107
@@ -82,14 +110,6 @@
82 getVideo(video) 110 getVideo(video)
83 }) 111 })
84 112
85 // Remove the video
86 $remove.on('click', function () {
87 // TODO
88 if (!confirm('Are you sure ?')) return
89
90 removeVideo(video)
91 })
92
93 if (!video.magnetUri) { 113 if (!video.magnetUri) {
94 $remove.css('display', 'none') 114 $remove.css('display', 'none')
95 } 115 }
diff --git a/routes/api/v1/pods.js b/routes/api/v1/pods.js
index 2bb8f89ab..2430b0d7e 100644
--- a/routes/api/v1/pods.js
+++ b/routes/api/v1/pods.js
@@ -6,6 +6,7 @@
6 var middleware = require('../../../middlewares') 6 var middleware = require('../../../middlewares')
7 var miscMiddleware = middleware.misc 7 var miscMiddleware = middleware.misc
8 var reqValidator = middleware.reqValidators.pods 8 var reqValidator = middleware.reqValidators.pods
9 var secureRequest = middleware.reqValidators.remote.secureRequest
9 var pods = require('../../../src/pods') 10 var pods = require('../../../src/pods')
10 11
11 function listPods (req, res, next) { 12 function listPods (req, res, next) {
@@ -24,8 +25,33 @@
24 }) 25 })
25 } 26 }
26 27
28 function removePods (req, res, next) {
29 pods.remove(req.body.signature.url, function (err) {
30 if (err) return next(err)
31
32 res.sendStatus(204)
33 })
34 }
35
27 function makeFriends (req, res, next) { 36 function makeFriends (req, res, next) {
28 pods.makeFriends(function (err) { 37 pods.hasFriends(function (err, has_friends) {
38 if (err) return next(err)
39
40 if (has_friends === true) {
41 // We need to quit our friends before make new ones
42 res.sendStatus(409)
43 } else {
44 pods.makeFriends(function (err) {
45 if (err) return next(err)
46
47 res.sendStatus(204)
48 })
49 }
50 })
51 }
52
53 function quitFriends (req, res, next) {
54 pods.quitFriends(function (err) {
29 if (err) return next(err) 55 if (err) return next(err)
30 56
31 res.sendStatus(204) 57 res.sendStatus(204)
@@ -34,7 +60,10 @@
34 60
35 router.get('/', miscMiddleware.cache(false), listPods) 61 router.get('/', miscMiddleware.cache(false), listPods)
36 router.get('/makefriends', miscMiddleware.cache(false), makeFriends) 62 router.get('/makefriends', miscMiddleware.cache(false), makeFriends)
63 router.get('/quitfriends', miscMiddleware.cache(false), quitFriends)
37 router.post('/', reqValidator.podsAdd, miscMiddleware.cache(false), addPods) 64 router.post('/', reqValidator.podsAdd, miscMiddleware.cache(false), addPods)
65 // Post because this is a secured request
66 router.post('/remove', secureRequest, miscMiddleware.decryptBody, removePods)
38 67
39 module.exports = router 68 module.exports = router
40})() 69})()
diff --git a/routes/api/v1/remoteVideos.js b/routes/api/v1/remoteVideos.js
index a104113b2..6ba6ce17b 100644
--- a/routes/api/v1/remoteVideos.js
+++ b/routes/api/v1/remoteVideos.js
@@ -22,7 +22,7 @@
22 videos.removeRemotes(req.body.signature.url, pluck(req.body.data, 'magnetUri'), function (err) { 22 videos.removeRemotes(req.body.signature.url, pluck(req.body.data, 'magnetUri'), function (err) {
23 if (err) return next(err) 23 if (err) return next(err)
24 24
25 res.status(204) 25 res.sendStatus(204)
26 }) 26 })
27 } 27 }
28 28
diff --git a/src/pods.js b/src/pods.js
index 8da216a55..defa9b1c1 100644
--- a/src/pods.js
+++ b/src/pods.js
@@ -43,7 +43,9 @@
43 } 43 }
44 44
45 // { url } 45 // { url }
46 // TODO: check if the pod is not already a friend
46 pods.add = function (data, callback) { 47 pods.add = function (data, callback) {
48 var videos = require('./videos')
47 logger.info('Adding pod: %s', data.url) 49 logger.info('Adding pod: %s', data.url)
48 50
49 var params = { 51 var params = {
@@ -58,13 +60,38 @@
58 return callback(err) 60 return callback(err)
59 } 61 }
60 62
63 videos.addRemotes(data.videos)
64
61 fs.readFile(utils.certDir + 'peertube.pub', 'utf8', function (err, cert) { 65 fs.readFile(utils.certDir + 'peertube.pub', 'utf8', function (err, cert) {
62 if (err) { 66 if (err) {
63 logger.error('Cannot read cert file.', { error: err }) 67 logger.error('Cannot read cert file.', { error: err })
64 return callback(err) 68 return callback(err)
65 } 69 }
66 70
67 return callback(null, { cert: cert }) 71 videos.listOwned(function (err, videos_list) {
72 if (err) {
73 logger.error('Cannot get the list of owned videos.', { error: err })
74 return callback(err)
75 }
76
77 return callback(null, { cert: cert, videos: videos_list })
78 })
79 })
80 })
81 }
82
83 pods.remove = function (url, callback) {
84 var videos = require('./videos')
85 logger.info('Removing %s pod.', url)
86
87 videos.removeAllRemotesOf(url, function (err) {
88 if (err) logger.error('Cannot remove all remote videos of %s.', url)
89
90 PodsDB.remove({ url: url }, function (err) {
91 if (err) return callback(err)
92
93 logger.info('%s pod removed.', url)
94 callback(null)
68 }) 95 })
69 }) 96 })
70 } 97 }
@@ -82,6 +109,7 @@
82 } 109 }
83 110
84 pods.makeFriends = function (callback) { 111 pods.makeFriends = function (callback) {
112 var videos = require('./videos')
85 var pods_score = {} 113 var pods_score = {}
86 114
87 logger.info('Make friends!') 115 logger.info('Make friends!')
@@ -137,43 +165,109 @@
137 } 165 }
138 166
139 function makeRequestsToWinningPods (cert, pods_list) { 167 function makeRequestsToWinningPods (cert, pods_list) {
140 var data = { 168 // Stop pool requests
141 url: http + '://' + host + ':' + port, 169 poolRequests.deactivate()
142 publicKey: cert 170 // Flush pool requests
143 } 171 poolRequests.forceSend()
172
173 // Get the list of our videos to send to our new friends
174 videos.listOwned(function (err, videos_list) {
175 if (err) throw err
176
177 var data = {
178 url: http + '://' + host + ':' + port,
179 publicKey: cert,
180 videos: videos_list
181 }
144 182
145 utils.makeMultipleRetryRequest( 183 utils.makeMultipleRetryRequest(
146 { method: 'POST', path: '/api/' + constants.API_VERSION + '/pods/', data: data }, 184 { method: 'POST', path: '/api/' + constants.API_VERSION + '/pods/', data: data },
147 185
148 pods_list, 186 pods_list,
149 187
150 function eachRequest (err, response, body, url, pod, callback_each_request) { 188 function eachRequest (err, response, body, url, pod, callback_each_request) {
151 // We add the pod if it responded correctly with its public certificate 189 // We add the pod if it responded correctly with its public certificate
152 if (!err && response.statusCode === 200) { 190 if (!err && response.statusCode === 200) {
153 pods.add({ url: pod.url, publicKey: body.cert, score: constants.FRIEND_BASE_SCORE }, function (err) { 191 pods.add({ url: pod.url, publicKey: body.cert, score: constants.FRIEND_BASE_SCORE }, function (err) {
154 if (err) { 192 if (err) logger.error('Error with adding %s pod.', pod.url, { error: err })
155 logger.error('Error with adding %s pod.', pod.url, { error: err })
156 }
157 193
194 videos.addRemotes(body.videos, function (err) {
195 if (err) logger.error('Error with adding videos of pod.', pod.url, { error: err })
196
197 logger.debug('Adding remote videos from %s.', pod.url, { videos: body.videos })
198 return callback_each_request()
199 })
200 })
201 } else {
202 logger.error('Error with adding %s pod.', pod.url, { error: err || new Error('Status not 200') })
158 return callback_each_request() 203 return callback_each_request()
159 }) 204 }
160 } else { 205 },
161 logger.error('Error with adding %s pod.', pod.url, { error: err || new Error('Status not 200') })
162 return callback_each_request()
163 }
164 },
165 206
166 function endRequests (err) { 207 function endRequests (err) {
167 if (err) { 208 // Now we made new friends, we can re activate the pool of requests
168 logger.error('There was some errors when we wanted to make friends.', { error: err }) 209 poolRequests.activate()
169 return callback(err) 210
211 if (err) {
212 logger.error('There was some errors when we wanted to make friends.', { error: err })
213 return callback(err)
214 }
215
216 logger.debug('makeRequestsToWinningPods finished.')
217 return callback(null)
170 } 218 }
219 )
220 })
221 }
222 }
171 223
172 logger.debug('makeRequestsToWinningPods finished.') 224 pods.quitFriends = function (callback) {
173 return callback(null) 225 // Stop pool requests
226 poolRequests.deactivate()
227 // Flush pool requests
228 poolRequests.forceSend()
229
230 PodsDB.find(function (err, pods) {
231 if (err) return callback(err)
232
233 var request = {
234 method: 'POST',
235 path: '/api/' + constants.API_VERSION + '/pods/remove',
236 sign: true,
237 encrypt: true,
238 data: {
239 url: 'me' // Fake data
174 } 240 }
175 ) 241 }
176 } 242
243 // Announce we quit them
244 utils.makeMultipleRetryRequest(request, pods, function () {
245 PodsDB.remove(function (err) {
246 poolRequests.activate()
247
248 if (err) return callback(err)
249
250 logger.info('Broke friends, so sad :(')
251
252 var videos = require('./videos')
253 videos.removeAllRemotes(function (err) {
254 if (err) return callback(err)
255
256 logger.info('Removed all remote videos.')
257 callback(null)
258 })
259 })
260 })
261 })
262 }
263
264 pods.hasFriends = function (callback) {
265 PodsDB.count(function (err, count) {
266 if (err) return callback(err)
267
268 var has_friends = (count !== 0)
269 callback(null, has_friends)
270 })
177 } 271 }
178 272
179 module.exports = pods 273 module.exports = pods
diff --git a/src/poolRequests.js b/src/poolRequests.js
index edb12b1e8..7f422f372 100644
--- a/src/poolRequests.js
+++ b/src/poolRequests.js
@@ -6,9 +6,11 @@
6 var constants = require('./constants') 6 var constants = require('./constants')
7 var logger = require('./logger') 7 var logger = require('./logger')
8 var database = require('./database') 8 var database = require('./database')
9 var pluck = require('lodash-node/compat/collection/pluck')
9 var PoolRequestsDB = database.PoolRequestsDB 10 var PoolRequestsDB = database.PoolRequestsDB
10 var PodsDB = database.PodsDB 11 var PodsDB = database.PodsDB
11 var utils = require('./utils') 12 var utils = require('./utils')
13 var VideosDB = database.VideosDB
12 14
13 var poolRequests = {} 15 var poolRequests = {}
14 16
@@ -90,11 +92,26 @@
90 } 92 }
91 93
92 function removeBadPods () { 94 function removeBadPods () {
93 PodsDB.remove({ score: 0 }, function (err, result) { 95 PodsDB.find({ score: 0 }, { _id: 1, url: 1 }, function (err, pods) {
94 if (err) throw err 96 if (err) throw err
95 97
96 var number_removed = result.result.n 98 if (pods.length === 0) return
97 if (number_removed !== 0) logger.info('Removed %d pod.', number_removed) 99
100 var urls = pluck(pods, 'url')
101 var ids = pluck(pods, '_id')
102
103 VideosDB.remove({ podUrl: { $in: urls } }, function (err, r) {
104 if (err) logger.error('Cannot remove videos from a pod that we removing.', { error: err })
105 var videos_removed = r.result.n
106 logger.info('Removed %d videos.', videos_removed)
107
108 PodsDB.remove({ _id: { $in: ids } }, function (err, r) {
109 if (err) logger.error('Cannot remove bad pods.', { error: err })
110
111 var pods_removed = r.result.n
112 logger.info('Removed %d pods.', pods_removed)
113 })
114 })
98 }) 115 })
99 } 116 }
100 117
@@ -126,9 +143,9 @@
126 utils.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished) 143 utils.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished)
127 144
128 function callbackEachPodFinished (err, response, body, url, pod, callback_each_pod_finished) { 145 function callbackEachPodFinished (err, response, body, url, pod, callback_each_pod_finished) {
129 if (err || response.statusCode !== 200) { 146 if (err || (response.statusCode !== 200 && response.statusCode !== 204)) {
130 bad_pods.push(pod._id) 147 bad_pods.push(pod._id)
131 logger.error('Error sending secure request to %s pod.', url, { error: err }) 148 logger.error('Error sending secure request to %s pod.', url, { error: err || new Error('Status code not 20x') })
132 } else { 149 } else {
133 good_pods.push(pod._id) 150 good_pods.push(pod._id)
134 } 151 }
@@ -180,5 +197,10 @@
180 clearInterval(timer) 197 clearInterval(timer)
181 } 198 }
182 199
200 poolRequests.forceSend = function () {
201 logger.info('Force pool requests sending.')
202 makePoolRequests()
203 }
204
183 module.exports = poolRequests 205 module.exports = poolRequests
184})() 206})()
diff --git a/src/utils.js b/src/utils.js
index 5880c6c90..176648a31 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -56,7 +56,7 @@
56 utils.makeMultipleRetryRequest = function (all_data, pods, callbackEach, callback) { 56 utils.makeMultipleRetryRequest = function (all_data, pods, callbackEach, callback) {
57 if (!callback) { 57 if (!callback) {
58 callback = callbackEach 58 callback = callbackEach
59 callbackEach = function () {} 59 callbackEach = null
60 } 60 }
61 61
62 var url = http + '://' + host + ':' + port 62 var url = http + '://' + host + ':' + port
@@ -71,9 +71,13 @@
71 // Make a request for each pod 71 // Make a request for each pod
72 async.each(pods, function (pod, callback_each_async) { 72 async.each(pods, function (pod, callback_each_async) {
73 function callbackEachRetryRequest (err, response, body, url, pod) { 73 function callbackEachRetryRequest (err, response, body, url, pod) {
74 callbackEach(err, response, body, url, pod, function () { 74 if (callbackEach !== null) {
75 callbackEach(err, response, body, url, pod, function () {
76 callback_each_async()
77 })
78 } else {
75 callback_each_async() 79 callback_each_async()
76 }) 80 }
77 } 81 }
78 82
79 var params = { 83 var params = {
diff --git a/src/videos.js b/src/videos.js
index 32f26abe7..90821fdf6 100644
--- a/src/videos.js
+++ b/src/videos.js
@@ -43,6 +43,18 @@
43 }) 43 })
44 } 44 }
45 45
46 videos.listOwned = function (callback) {
47 // If namePath is not null this is *our* video
48 VideosDB.find({ namePath: { $ne: null } }, function (err, videos_list) {
49 if (err) {
50 logger.error('Cannot get list of the videos.', { error: err })
51 return callback(err)
52 }
53
54 return callback(null, videos_list)
55 })
56 }
57
46 videos.add = function (data, callback) { 58 videos.add = function (data, callback) {
47 var video_file = data.video 59 var video_file = data.video
48 var video_data = data.data 60 var video_data = data.data
@@ -131,6 +143,8 @@
131 143
132 // Use the magnet Uri because the _id field is not the same on different servers 144 // Use the magnet Uri because the _id field is not the same on different servers
133 videos.removeRemotes = function (fromUrl, magnetUris, callback) { 145 videos.removeRemotes = function (fromUrl, magnetUris, callback) {
146 if (callback === undefined) callback = function () {}
147
134 VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) { 148 VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) {
135 if (err || !videos) { 149 if (err || !videos) {
136 logger.error('Cannot find the torrent URI of these remote videos.') 150 logger.error('Cannot find the torrent URI of these remote videos.')
@@ -155,14 +169,34 @@
155 return callback(err) 169 return callback(err)
156 } 170 }
157 171
172 logger.info('Removed remote videos from %s.', fromUrl)
158 callback(null) 173 callback(null)
159 }) 174 })
160 }) 175 })
161 }) 176 })
162 } 177 }
163 178
179 videos.removeAllRemotes = function (callback) {
180 VideosDB.remove({ namePath: null }, function (err) {
181 if (err) return callback(err)
182
183 callback(null)
184 })
185 }
186
187 videos.removeAllRemotesOf = function (fromUrl, callback) {
188 VideosDB.remove({ podUrl: fromUrl }, function (err) {
189 if (err) return callback(err)
190
191 callback(null)
192 })
193 }
194
164 // { name, magnetUri, podUrl } 195 // { name, magnetUri, podUrl }
196 // TODO: avoid doublons
165 videos.addRemotes = function (videos, callback) { 197 videos.addRemotes = function (videos, callback) {
198 if (callback === undefined) callback = function () {}
199
166 var to_add = [] 200 var to_add = []
167 201
168 async.each(videos, function (video, callback_each) { 202 async.each(videos, function (video, callback_each) {
diff --git a/test/api/friendsAdvanced.js b/test/api/friendsAdvanced.js
index a638eb0d4..b24cd39c3 100644
--- a/test/api/friendsAdvanced.js
+++ b/test/api/friendsAdvanced.js
@@ -1,6 +1,7 @@
1;(function () { 1;(function () {
2 'use strict' 2 'use strict'
3 3
4 var async = require('async')
4 var chai = require('chai') 5 var chai = require('chai')
5 var expect = chai.expect 6 var expect = chai.expect
6 7
@@ -10,8 +11,12 @@
10 var apps = [] 11 var apps = []
11 var urls = [] 12 var urls = []
12 13
13 function makeFriend (pod_number, callback) { 14 function makeFriends (pod_number, callback) {
14 return utils.makeFriend(urls[pod_number - 1], callback) 15 return utils.makeFriends(urls[pod_number - 1], callback)
16 }
17
18 function quitFriends (pod_number, callback) {
19 return utils.quitFriends(urls[pod_number - 1], callback)
15 } 20 }
16 21
17 function getFriendsList (pod_number, end) { 22 function getFriendsList (pod_number, end) {
@@ -26,7 +31,11 @@
26 return utils.uploadVideo(urls[pod_number - 1], name, description, fixture, callback) 31 return utils.uploadVideo(urls[pod_number - 1], name, description, fixture, callback)
27 } 32 }
28 33
29 beforeEach(function (done) { 34 function getVideos (pod_number, callback) {
35 return utils.getVideosList(urls[pod_number - 1], callback)
36 }
37
38 before(function (done) {
30 this.timeout(30000) 39 this.timeout(30000)
31 utils.runMultipleServers(6, function (apps_run, urls_run) { 40 utils.runMultipleServers(6, function (apps_run, urls_run) {
32 apps = apps_run 41 apps = apps_run
@@ -35,7 +44,7 @@
35 }) 44 })
36 }) 45 })
37 46
38 afterEach(function (done) { 47 after(function (done) {
39 apps.forEach(function (app) { 48 apps.forEach(function (app) {
40 process.kill(-app.pid) 49 process.kill(-app.pid)
41 }) 50 })
@@ -53,11 +62,11 @@
53 this.timeout(20000) 62 this.timeout(20000)
54 63
55 // Pod 3 makes friend with the first one 64 // Pod 3 makes friend with the first one
56 makeFriend(3, function () { 65 makeFriends(3, function () {
57 // Pod 4 makes friend with the second one 66 // Pod 4 makes friend with the second one
58 makeFriend(4, function () { 67 makeFriends(4, function () {
59 // Now if the fifth wants to make friends with the third et the first 68 // Now if the fifth wants to make friends with the third et the first
60 makeFriend(5, function () { 69 makeFriends(5, function () {
61 setTimeout(function () { 70 setTimeout(function () {
62 // It should have 0 friends 71 // It should have 0 friends
63 getFriendsList(5, function (err, res) { 72 getFriendsList(5, function (err, res) {
@@ -73,13 +82,30 @@
73 }) 82 })
74 }) 83 })
75 84
85 it('Should quit all friends', function (done) {
86 this.timeout(10000)
87 quitFriends(1, function () {
88 quitFriends(2, function () {
89 async.each([ 1, 2, 3, 4, 5, 6 ], function (i, callback) {
90 getFriendsList(i, function (err, res) {
91 if (err) throw err
92 expect(res.body.length).to.equal(0)
93 callback()
94 })
95 }, function () {
96 done()
97 })
98 })
99 })
100 })
101
76 it('Should make friends with the pods 1, 2, 3', function (done) { 102 it('Should make friends with the pods 1, 2, 3', function (done) {
77 this.timeout(150000) 103 this.timeout(150000)
78 104
79 // Pods 1, 2, 3 and 4 become friends (yes this is beautiful) 105 // Pods 1, 2, 3 and 4 become friends (yes this is beautiful)
80 makeFriend(2, function () { 106 makeFriends(2, function () {
81 makeFriend(1, function () { 107 makeFriends(1, function () {
82 makeFriend(4, function () { 108 makeFriends(4, function () {
83 // Kill the server 4 109 // Kill the server 4
84 apps[3].kill() 110 apps[3].kill()
85 111
@@ -99,7 +125,7 @@
99 expect(res.body.length).to.equal(3) 125 expect(res.body.length).to.equal(3)
100 126
101 // Pod 6 ask pod 1, 2 and 3 127 // Pod 6 ask pod 1, 2 and 3
102 makeFriend(6, function () { 128 makeFriends(6, function () {
103 getFriendsList(6, function (err, res) { 129 getFriendsList(6, function (err, res) {
104 if (err) throw err 130 if (err) throw err
105 131
@@ -125,5 +151,45 @@
125 }) 151 })
126 }) 152 })
127 }) 153 })
154
155 it('Should pod 1 quit friends', function (done) {
156 this.timeout(25000)
157 // Upload a video on server 3 for aditionnal tests
158 uploadVideo(3, function () {
159 setTimeout(function () {
160 quitFriends(1, function () {
161 // Remove pod 1 from pod 2
162 getVideos(1, function (err, res) {
163 if (err) throw err
164 expect(res.body).to.be.an('array')
165 expect(res.body.length).to.equal(2)
166
167 getVideos(2, function (err, res) {
168 if (err) throw err
169 expect(res.body).to.be.an('array')
170 expect(res.body.length).to.equal(3)
171 done()
172 })
173 })
174 })
175 }, 15000)
176 })
177 })
178
179 it('Should make friends between pod 1 and 2 and exchange their videos', function (done) {
180 this.timeout(20000)
181 makeFriends(1, function () {
182 setTimeout(function () {
183 getVideos(1, function (err, res) {
184 if (err) throw err
185
186 expect(res.body).to.be.an('array')
187 expect(res.body.length).to.equal(5)
188
189 done()
190 })
191 }, 5000)
192 })
193 })
128 }) 194 })
129})() 195})()
diff --git a/test/api/friendsBasic.js b/test/api/friendsBasic.js
index 43ec41633..15b83d421 100644
--- a/test/api/friendsBasic.js
+++ b/test/api/friendsBasic.js
@@ -9,6 +9,29 @@
9 var utils = require('./utils') 9 var utils = require('./utils')
10 10
11 describe('Test basic friends', function () { 11 describe('Test basic friends', function () {
12 function testMadeFriends (urls, url_to_test, callback) {
13 var friends = []
14 for (var i = 0; i < urls.length; i++) {
15 if (urls[i] === url_to_test) continue
16 friends.push(urls[i])
17 }
18
19 utils.getFriendsList(url_to_test, function (err, res) {
20 if (err) throw err
21
22 var result = res.body
23 var result_urls = [ result[0].url, result[1].url ]
24 expect(result).to.be.an('array')
25 expect(result.length).to.equal(2)
26 expect(result_urls[0]).to.not.equal(result_urls[1])
27
28 var error_string = 'Friends url do not correspond for ' + url_to_test
29 expect(friends).to.contain(result_urls[0], error_string)
30 expect(friends).to.contain(result_urls[1], error_string)
31 callback()
32 })
33 }
34
12 var apps = [] 35 var apps = []
13 var urls = [] 36 var urls = []
14 37
@@ -41,29 +64,6 @@
41 it('Should make friends', function (done) { 64 it('Should make friends', function (done) {
42 this.timeout(10000) 65 this.timeout(10000)
43 66
44 function testMadeFriends (urls, url_to_test, callback) {
45 var friends = []
46 for (var i = 0; i < urls.length; i++) {
47 if (urls[i] === url_to_test) continue
48 friends.push(urls[i])
49 }
50
51 utils.getFriendsList(url_to_test, function (err, res) {
52 if (err) throw err
53
54 var result = res.body
55 var result_urls = [ result[0].url, result[1].url ]
56 expect(result).to.be.an('array')
57 expect(result.length).to.equal(2)
58 expect(result_urls[0]).to.not.equal(result_urls[1])
59
60 var error_string = 'Friends url do not correspond for ' + url_to_test
61 expect(friends).to.contain(result_urls[0], error_string)
62 expect(friends).to.contain(result_urls[1], error_string)
63 callback()
64 })
65 }
66
67 var path = '/api/v1/pods/makefriends' 67 var path = '/api/v1/pods/makefriends'
68 68
69 // The second pod make friend with the third 69 // The second pod make friend with the third
@@ -118,8 +118,48 @@
118 }) 118 })
119 }) 119 })
120 120
121 // TODO 121 it('Should not be allowed to make friend again', function (done) {
122 it('Should not be able to make friends again') 122 utils.makeFriends(urls[1], 409, done)
123 })
124
125 it('Should quit friends of pod 2', function (done) {
126 utils.quitFriends(urls[1], function () {
127 utils.getFriendsList(urls[1], function (err, res) {
128 if (err) throw err
129
130 var result = res.body
131 expect(result).to.be.an('array')
132 expect(result.length).to.equal(0)
133
134 // Other pods shouldn't have pod 2 too
135 async.each([ urls[0], urls[2] ], function (url, callback) {
136 utils.getFriendsList(url, function (err, res) {
137 if (err) throw err
138
139 var result = res.body
140 expect(result).to.be.an('array')
141 expect(result.length).to.equal(1)
142 expect(result[0].url).not.to.be.equal(urls[1])
143 callback()
144 })
145 }, function (err) {
146 if (err) throw err
147 done()
148 })
149 })
150 })
151 })
152
153 it('Should allow pod 2 to make friend again', function (done) {
154 utils.makeFriends(urls[1], function () {
155 async.each(urls, function (url, callback) {
156 testMadeFriends(urls, url, callback)
157 }, function (err) {
158 if (err) throw err
159 done()
160 })
161 })
162 })
123 163
124 after(function (done) { 164 after(function (done) {
125 apps.forEach(function (app) { 165 apps.forEach(function (app) {
diff --git a/test/api/multiplePods.js b/test/api/multiplePods.js
index a831e0fa6..531e1ef33 100644
--- a/test/api/multiplePods.js
+++ b/test/api/multiplePods.js
@@ -22,12 +22,12 @@
22 urls = urls_run 22 urls = urls_run
23 23
24 // The second pod make friend with the third 24 // The second pod make friend with the third
25 utils.makeFriend(urls[1], function (err, res) { 25 utils.makeFriends(urls[1], function (err, res) {
26 if (err) throw err 26 if (err) throw err
27 27
28 // Wait for the request between pods 28 // Wait for the request between pods
29 setTimeout(function () { 29 setTimeout(function () {
30 utils.makeFriend(urls[0], function (err, res) { 30 utils.makeFriends(urls[0], function (err, res) {
31 if (err) throw err 31 if (err) throw err
32 32
33 webtorrent.create({ host: 'client', port: '1' }, function () { 33 webtorrent.create({ host: 'client', port: '1' }, function () {
diff --git a/test/api/utils.js b/test/api/utils.js
index 8d059b01c..b00890539 100644
--- a/test/api/utils.js
+++ b/test/api/utils.js
@@ -34,13 +34,36 @@
34 .end(end) 34 .end(end)
35 } 35 }
36 36
37 function makeFriend (url, callback) { 37 function makeFriends (url, expected_status, callback) {
38 if (!callback) {
39 callback = expected_status
40 expected_status = 204
41 }
42
38 var path = '/api/v1/pods/makefriends' 43 var path = '/api/v1/pods/makefriends'
39 44
40 // The first pod make friend with the third 45 // The first pod make friend with the third
41 request(url) 46 request(url)
42 .get(path) 47 .get(path)
43 .set('Accept', 'application/json') 48 .set('Accept', 'application/json')
49 .expect(expected_status)
50 .end(function (err, res) {
51 if (err) throw err
52
53 // Wait for the request between pods
54 setTimeout(function () {
55 callback()
56 }, 1000)
57 })
58 }
59
60 function quitFriends (url, callback) {
61 var path = '/api/v1/pods/quitfriends'
62
63 // The first pod make friend with the third
64 request(url)
65 .get(path)
66 .set('Accept', 'application/json')
44 .expect(204) 67 .expect(204)
45 .end(function (err, res) { 68 .end(function (err, res) {
46 if (err) throw err 69 if (err) throw err
@@ -152,7 +175,8 @@
152 flushTests: flushTests, 175 flushTests: flushTests,
153 getFriendsList: getFriendsList, 176 getFriendsList: getFriendsList,
154 getVideosList: getVideosList, 177 getVideosList: getVideosList,
155 makeFriend: makeFriend, 178 makeFriends: makeFriends,
179 quitFriends: quitFriends,
156 removeVideo: removeVideo, 180 removeVideo: removeVideo,
157 runMultipleServers: runMultipleServers, 181 runMultipleServers: runMultipleServers,
158 runServer: runServer, 182 runServer: runServer,
diff --git a/views/panel.jade b/views/panel.jade
index cec83a9e1..0d124fb7e 100644
--- a/views/panel.jade
+++ b/views/panel.jade
@@ -1,13 +1,17 @@
1menu(class='col-md-2') 1menu(class='col-md-2')
2 2
3 div(id='panel_get_videos' class='panel_button') 3 div(id='panel_get_videos' class='panel_button')
4 span(class='glyphicon glyphicon-list') 4 span(class='glyphicon glyphicon-list')
5 | Get videos 5 | Get videos
6 6
7 div(id='panel_upload_video' class='panel_button') 7 div(id='panel_upload_video' class='panel_button')
8 span(class='glyphicon glyphicon-cloud-upload') 8 span(class='glyphicon glyphicon-cloud-upload')
9 | Upload a video 9 | Upload a video
10 10
11 div(id='panel_make_friends' class='panel_button') 11 div(id='panel_make_friends' class='panel_button')
12 span(class='glyphicon glyphicon-magnet') 12 span(class='glyphicon glyphicon-user')
13 | Make friends \ No newline at end of file 13 | Make friends
14
15 div(id='panel_quit_friends' class='panel_button')
16 span(class='glyphicon glyphicon-plane')
17 | Quit friends