From 4b96cbe9ad23e39c4a41c1ee0f1450c9c04e14b3 Mon Sep 17 00:00:00 2001 From: David Baldwynn Date: Fri, 4 Dec 2015 20:03:30 -0800 Subject: [PATCH] added ng-file-upload to jsdelivr --- .gitignore | 47 +++++++++++++ README.md | 3 + karma.conf.js | 57 +++++++++++++++ package.json | 40 +++++++++++ src/app.coffee | 40 ++++++----- src/index.jade | 22 +++--- test/spec.js | 184 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 364 insertions(+), 29 deletions(-) create mode 100644 .gitignore create mode 100644 karma.conf.js create mode 100644 package.json create mode 100644 test/spec.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..045a725 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ + +# Created by https://www.gitignore.io/api/node,osx +### HarpJS ### +www + +### Node ### +# Logs +logs +*.log +npm-debug.log* + + +# Dependency directory +# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git +node_modules + +# Optional npm cache directory +.npm + + +### OSX ### +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + diff --git a/README.md b/README.md index 8eca79f..bcaff37 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ Disable by running this: localStorage.removeItem('debug') ``` +###Testing +To test BTorrent, run `npm test` + ### Help βTorrent - **[Create a new issue](https://github.com/DiegoRBaquero/bTorrent/issues/new)** to report bugs or suggest new features - **[Send a PR](https://github.com/DiegoRBaquero/BTorrent/pull/new/master)** with your changes diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..4023dea --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,57 @@ +'use strict' + +/** + * Module dependencies. + */ + +// Karma configuration +module.exports = function (karmaConfig) { + + karmaConfig.set({ + // Frameworks to use + frameworks: ['jasmine'], + // List of files / patterns to load in the browser + files: ['node_modules/webtorrent/*min.js', + 'node_modules/angular/*min.js', + 'node_modules/angular-mocks/angular-mocks.js', + 'node_modules/ng-file-upload/dist/*min.js', + 'node_modules/webtorrent/*min.js', + 'node_modules/moment/moment.js', + 'www/*', + 'test/*.js'], + + // Test results reporter to use + // Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' + reporters: ['progress'], + + // Web server port + port: 9876, + + // Enable / disable colors in the output (reporters and logs) + colors: true, + + // Level of logging + // Possible values: karmaConfig.LOG_DISABLE || karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN || karmaConfig.LOG_INFO || karmaConfig.LOG_DEBUG + logLevel: karmaConfig.LOG_INFO, + + // Enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + // Start these browsers, currently available: + // - Chrome + // - ChromeCanary + // - Firefox + // - Opera + // - Safari (only Mac) + // - PhantomJS2 + // - IE (only Windows) + browsers: ['PhantomJS2'], + + // If browser does not capture in given timeout [ms], kill it + captureTimeout: 60000, + + // Continuous Integration mode + // If true, it capture browsers, run tests and exit + singleRun: true + }) +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5f862c4 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "btorrent", + "version": "0.5.3", + "description": "Browser based torrenting client", + "main": "index.js", + "scripts": { + "test": "karma start" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/DiegoRBaquero/BTorrent.git" + }, + "keywords": [ + "webtorrent", + "torrent", + "torrent", + "client" + ], + "author": "Diego R Baquero", + "license": "MIT", + "bugs": { + "url": "https://github.com/DiegoRBaquero/BTorrent/issues" + }, + "homepage": "https://github.com/DiegoRBaquero/BTorrent#readme", + "dependencies": { + "harp": "^0.20.1" + }, + "devDependencies": { + "angular": "^1.4.8", + "angular-mocks": "^1.4.8", + "jasmine-core": "^2.4.1", + "karma": "^0.13.15", + "karma-jasmine": "^0.3.6", + "karma-phantomjs2-launcher": "^0.3.2", + "moment": "^2.10.6", + "ng-file-upload": "^10.1.8", + "phantomjs2": "git+https://github.com/davidchin/phantomjs2.git#reinstate_bin", + "webtorrent": "^0.63.2" + } +} diff --git a/src/app.coffee b/src/app.coffee index 28e177a..b5f3f32 100644 --- a/src/app.coffee +++ b/src/app.coffee @@ -13,7 +13,8 @@ opts = {announce: trackers} client = new WebTorrent debug = window.localStorage ? window.localStorage.getItem('debug') == '*':false -app = angular.module 'bTorrent', [], ['$compileProvider','$locationProvider', ($compileProvider, $locationProvider) -> +app = angular.module 'bTorrent', [], ['$compileProvider','$locationProvider', +($compileProvider, $locationProvider) -> $compileProvider.aHrefSanitizationWhitelist /^\s*(https?|magnet|blob|javascript):/ $locationProvider.html5Mode( enabled: true @@ -57,27 +58,28 @@ app.controller 'bTorrentCtrl', ['$scope','$http','$log','$location', ($scope, $h downloading $scope.uploadSeed = (file) -> - $scope.client.processing = true - dbg 'Seeding ' + file.name - $scope.client.seed file, opts, $scope.onSeed - return - $scope.uploadTorrent = (file) -> - $scope.client.processing = true - dbg('Adding ') + file.name - $scope.client.add file, opts, $scope.onTorrent - $scope.magnetLinkInput = '' - return + $scope.client.processing = true + dbg('Seeding ' + file.name) + $scope.client.seed file, opts, $scope.onSeed + return - $scope.addByMagnet = () -> - if $scope.magnetLinkInput && $scope.magnetLinkInput.length - $scope.client.processing = true - $scope.magnetLinkInput += '' + $scope.uploadTorrent = (file) -> + $scope.client.processing = true + dbg('Adding ') + file.name + $scope.client.add file, opts, $scope.onTorrent + $scope.magnetLinkInput = '' + return - dbg('Adding magnetLinkInput: ' + $scope.magnetLinkInput) - $scope.client.add($scope.magnetLinkInput, opts, $scope.onTorrent) + $scope.addByMagnet = () -> + if $scope.magnetLinkInput && $scope.magnetLinkInput.length + $scope.client.processing = true + $scope.magnetLinkInput += '' - $scope.magnetLinkInput = '' - return + dbg('Adding magnetLinkInput: ' + $scope.magnetLinkInput) + $scope.client.add($scope.magnetLinkInput, opts, $scope.onTorrent) + + $scope.magnetLinkInput = '' + return $scope.toggleTorrent = (torrent) -> if torrent.showFiles diff --git a/src/index.jade b/src/index.jade index b32b506..8dc7c8c 100644 --- a/src/index.jade +++ b/src/index.jade @@ -8,7 +8,7 @@ html(ng-app='bTorrent', lang='en') meta(name='keywords', content='βTorrent, btorrent, client, webtorrent, browser, torrent, stream, bittorrent') meta(name='author', content='Diego Rodríguez Baquero - DiegoRBaquero') meta(name='viewport', content='width=device-width, initial-scale=1') - script(src='https://cdn.jsdelivr.net/g/webtorrent@0.62,momentjs@2.10,angularjs@1.4') + script(src='https://cdn.jsdelivr.net/g/webtorrent@0.62,momentjs@2.10,angularjs@1.4,ng-file-upload') link(rel='stylesheet', href='https://cdn.jsdelivr.net/g/normalize@3.0,skeleton@2.0') link(rel='stylesheet', href='https://cdn.jsdelivr.net/fontawesome/4.5/css/font-awesome.min.css') link(rel='stylesheet', href='style.css') @@ -21,16 +21,18 @@ html(ng-app='bTorrent', lang='en') .row .twelve.columns .row - .five.columns - input#torrentInput.u-full-width(type='text', placeholder='magnet link or hash', ng-model='torrentInput') - .two.columns - button.button-primary(ng-click='fromInput()') - i.fa.fa-download - | Download - .five.columns.u-pull-right - input#fileUpload(type='file', style='display: none;', onchange='angular.element(this).scope().uploadFile2(this)') + .three.columns + input#magnetLinkInput.u-full-width(type='text', placeholder='magnet link or hash', ng-model='magnetLinkInput') + .three.columns + button.button-secondary(ng-click='addByMagnet()', ng-disabled="!magnetLinkInput") + | Add Magnet Link + .four.columns + button.button-primary(ngf-select='uploadTorrent($file)') + i.fa.fa-upload + | Add Torrent File + .two.columns.u-pull-right label.u-pull-right - button.button-primary(ng-click='uploadFile()') + .button(ngf-select='uploadSeed($file)') i.fa.fa-upload | Seed a file table.u-full-width diff --git a/test/spec.js b/test/spec.js new file mode 100644 index 0000000..00102f0 --- /dev/null +++ b/test/spec.js @@ -0,0 +1,184 @@ +(function () { + // Articles Controller Spec + describe('Btorrent Controller Tests', function () { + // Initialize global variables + var bTorrentCtrl, + scope, + $stateParams, + WebTorrent + + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function () { + jasmine.addMatchers({ + toEqualData: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + return { + pass: angular.equals(actual, expected) + } + } + } + } + }) + }) + + // Load the main application module + beforeEach(module('bTorrent')) + + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function ($controller, $rootScope) { + // Set a new global scope + scope = $rootScope.$new() + + // Initialize the controller. + bTorrentCtrl = $controller('bTorrentCtrl', { + $scope: scope + }) + expect(scope.seedIt).toBe(true) + })) + + describe('scope.done()', function () { + beforeEach(function () { + scope.client.torrents = [{ + fileName: 'torrent1.torrent', + showFiles: false + }, + { + fileName: 'torrent2.torrent', + showFiles: true + }, + { + fileName: 'torrent3.torrent', + showFiles: false + }] + }) + + it('scope.done() should return false if at least one torrent is not done', function () { + // Run controller functionality + var isDone = scope.client.done() + + // Test scope value + expect(isDone).toBe(false) + }) + + it('scope.done() should return true if all torrents are done', function () { + scope.client.torrents.map(function(torrent){ + torrent.done = true + return torrent + }) + + // Run controller functionality + var isDone = scope.client.done() + + // Test scope value + expect(isDone).toBe(true) + }) + }) + + describe('scope.addByMagnet()', function() { + beforeEach(function () { + scope.client.torrents = [{ + fileName: 'torrent1.torrent', + showFiles: false + }, + { + fileName: 'torrent2.torrent', + showFiles: true + }, + { + fileName: 'torrent3.torrent', + showFiles: false + }] + + spyOn(scope.client, 'add').and.callFake(function (torrentMagnet, opts, cb) { + scope.client.torrents.push({ + magnetURI: torrentMagnet, + showFiles: false, + done: false + }) + }) + }) + + it('scope.addByMagnet() should not do anything if torrentInput is undefined', function () { + expect(scope.magnetLinkInput).not.toEqual(jasmine.anything()) + scope.client.processing = false + // Run controller functionality + scope.addByMagnet() + + // Test scope value + expect(scope.client.processing).toBe(false) + expect(scope.client.torrents.length).toBe(3) + }) + + it('scope.addByMagnet() should not do anything if torrentInput is an empty string', function () { + scope.magnetLinkInput = '' + scope.client.processing = false + // Run controller functionality + scope.addByMagnet() + + // Test scope value + expect(scope.client.processing).toBe(false) + expect(scope.client.torrents.length).toBe(3) + }) + + it('scope.addByMagnet() should add torrent if torrentInput is not undefined or empty', function () { + scope.magnetLinkInput = 'magnet:?xt=urn:btih:BFE0F947FAF031D7A77E0F582365F0AB4E4E3323&dn=ubuntu+linux+toolbox+1000+commands+for+ubuntu+and+debian+power+users+2nd+edition+true+pdf+by+christopher+negus+pradyutvam2+cpul+wiley+pdf+latest&tr=udp%3A%2F%2F9.rarbg.com%3A2710%2Fannounce&tr=udp%3A%2F%2Fglotorrents.pw%3A6969%2Fannounce' + scope.client.processing = false + // Run controller functionality + scope.addByMagnet() + + // Test scope value + expect(scope.client.processing).toBe(true) + expect(scope.client.torrents.length).toBe(4) + expect(scope.client.torrents[3]).toEqualData({ + magnetURI: 'magnet:?xt=urn:btih:BFE0F947FAF031D7A77E0F582365F0AB4E4E3323&dn=ubuntu+linux+toolbox+1000+commands+for+ubuntu+and+debian+power+users+2nd+edition+true+pdf+by+christopher+negus+pradyutvam2+cpul+wiley+pdf+latest&tr=udp%3A%2F%2F9.rarbg.com%3A2710%2Fannounce&tr=udp%3A%2F%2Fglotorrents.pw%3A6969%2Fannounce', + showFiles: false, + done: false + }) + }) + }) + + it('scope.destroyedTorrent() should set scope.client.processing to false', function () { + scope.client.processing = false + // Run controller functionality + scope.destroyedTorrent() + + // Test scope value + expect(scope.client.processing).toBe(false) + }) + + describe('scope.toggleTorrent()', function () { + beforeEach(function () { + scope.client.torrents = [{ + fileName: 'torrent1.torrent', + showFiles: false + }, + { + fileName: 'torrent2.torrent', + showFiles: true + }, + { + fileName: 'torrent3.torrent', + showFiles: false + }] + }) + + it('scope.toggleTorrent() should show a torrent if it is hidden', function () { + // Run controller functionality + scope.toggleTorrent(scope.client.torrents[2]) + + // Test scope value + expect(scope.client.torrents[2].showFiles).toBe(true) + expect(scope.client.torrents[1].showFiles).toBe(false) + expect(scope.client.torrents[0].showFiles).toBe(false) + expect(scope.sTorrent).toEqualData(scope.client.torrents[2]) + }) + }) + }) +}())