Auto test and install methods added

This commit is contained in:
Joe Vu 2014-12-16 23:33:48 -08:00
parent 79205951f8
commit 29a92fd51b
9 changed files with 294 additions and 81 deletions

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
# Development generated files
.idea
atlassian-ide-plugin.xml
# Folders
node_modules
bower_components
dist
.grunt
# Debug files
_SpecRunner.html
npm-debug.log

3
.travis.yml Normal file
View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- "0.11"

76
Gruntfile.js Normal file
View File

@ -0,0 +1,76 @@
module.exports = function(grunt) {
grunt.initConfig({
run_node: {
start: {
files: { src: [ 'tests/mock-file-server.js'] }
}
},
stop_node: { stop: {} },
run: {
installBower: {
cmd: 'node',
args: [
'./node_modules/bower/bin/bower',
'install'
]
},
killAllNodeWindows: {
cmd: 'taskkill',
args: [
'/f',
'/im',
'node.exe'
]
},
killAllNodeMac: {
cmd: 'killall',
args: [
'node'
]
}
},
jasmine: {
host: 'http://localhost:8888/',
options: {
specs: ['tests/*spec.js'],
//keepRunner: true,
vendor: [
"bower_components/Blob/Blob.js",
"bower_components/jquery/dist/jquery.min.js",
"bower_components/underscore/underscore-min.js",
"bower_components/backbone/backbone.js",
"backbone-model-file-upload.js"
]
}
},
parallel: {
runTest: {
tasks: [{
grunt: true,
args: ['run:mockServer']
}, {
grunt: true,
args: ['jasmine']
}, {
cmd: 'node:kill'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-run');
grunt.loadNpmTasks('grunt-parallel');
grunt.loadNpmTasks('grunt-run-node');
grunt.registerTask('test', ['run:installBower','run_node','jasmine','stop_node']);
grunt.registerTask('resetNodeWin', ['run:killAllNodeWindows']);
grunt.registerTask('resetNodeMac', ['run:killAllNodeMac']);
};

8
bower.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "backbone-model-file-upload tests",
"dependencies": {
"jquery": "~2.1.1",
"backbone": "~1.1.2",
"Blob": "*"
}
}

38
package.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "backbone-model-file-upload",
"version": "0.5.3",
"description": "A concise, non-iframe, & pure XHR2/AJAX Backbone.model file upload. (Good for IE >= 10, FF, Chrome.)",
"main": "backbone-model-file-upload.js",
"directories": {
"test": "tests"
},
"dependencies": {
"bower": "^1.3.12",
"formidable": "~1.0.15",
"grunt": "^0.4.5",
"grunt-contrib-jasmine": "^0.6.5",
"grunt-run": "^0.3.0",
"grunt-run-node": "^0.1.0",
"lodash": "~2.4.1"
},
"scripts": {
"test": "grunt test"
},
"repository": {
"type": "git",
"url": "https://github.com/homeslicesolutions/backbone-model-file-upload.git"
},
"keywords": [
"backbone",
"fileupload",
"file",
"model",
"multipart"
],
"author": "Joe Vu",
"license": "MIT",
"bugs": {
"url": "https://github.com/homeslicesolutions/backbone-model-file-upload/issues"
},
"homepage": "https://github.com/homeslicesolutions/backbone-model-file-upload"
}

View File

@ -1,10 +1,16 @@
!function(){
'use strict'
'use strict';
describe('Testing Backbone Model Plugin', function(){
Backbone.$.ajaxSetup({
headers: {
"Access-Control-Allow-Origin": "*"
}
});
var File = Backbone.Model.extend({
url: 'upload-test.php',
url: 'http://localhost:8989/',
fileAttribute: 'fileAttachment'
});
@ -36,11 +42,15 @@
// Assert
expect(model.get('from')).toBe('sample@email.com');
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
// Assert Blob (phantomJS can't do Blobs so just test minimal attributes)
expect(model.get('fileAttachment').size).toBe(28);
expect(model.get('fileAttachment').type).toBe('text/html');
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
done();
})
});
// Act
fileModel.save(null);
@ -54,7 +64,11 @@
// Assert
expect(model.get('from')).toBe('sample@email.com');
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
// Assert Blob (phantomJS can't do Blobs so just test minimal attributes)
expect(model.get('fileAttachment').size).toBe(28);
expect(model.get('fileAttachment').type).toBe('text/html');
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
done();
@ -72,7 +86,10 @@
// Assert
expect(model.get('from')).toBe('sample@email.com');
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
// Assert Blob (phantomJS can't do Blobs so just test minimal attributes)
expect(model.get('fileAttachment').size).toBe(28);
expect(model.get('fileAttachment').type).toBe('text/html');
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
done();
@ -90,7 +107,10 @@
// Assert
expect(model.get('from')).toBe('sample@email.com');
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
// Assert Blob (phantomJS can't do Blobs so just test minimal attributes)
expect(model.get('fileAttachment').size).toBe(28);
expect(model.get('fileAttachment').type).toBe('text/html');
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
done();
@ -164,7 +184,10 @@
fileModel.on('sync', function(model){
// Assert
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
// Assert Blob (phantomJS can't do Blobs so just test minimal attributes)
expect(model.get('fileAttachment').size).toBe(28);
expect(model.get('fileAttachment').type).toBe('text/html');
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
setTimeout(function(){
expect(changed).not.toBeTruthy();
@ -175,7 +198,7 @@
fileModel.on('change', function(){
changed = true;
})
});
// Act
fileModel.save({fileAttachment: simulatedFileObj}, {silent: true});
@ -201,7 +224,7 @@
fileModel.on('change', function(){
changed = true;
})
});
// Act
fileModel.save({from: "yes"}, {silent: true});

View File

@ -1,23 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css" />
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script type="text/javascript" src="../backbone-model-file-upload.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
</head>
<body>
<script type="text/javascript" src="backbone-model-file-upload.spec.js"></script>
</body>
</html>

122
tests/mock-file-server.js Normal file
View File

@ -0,0 +1,122 @@
'use strict';
var http = require('http'),
formidable = require('formidable'),
fs = require('fs'),
_ = require('lodash');
var options = {
host: 'localhost',
port: 8989
};
var unflatten = function(path, obj, value) {
var key, child, output;
if (Object.prototype.toString.call(path) == '[object Object]') {
output = {};
for (key in path) {
if (path.hasOwnProperty(key)) {
unflatten(key.split('.'), output, path[key]);
}
}
return output;
}
key = path.shift();
if (!path.length) {
obj[key] = value;
return obj;
}
if ((child = obj[key]) == void 0) {
child = obj[key] = {};
}
unflatten(path, child, value);
return obj;
};
var server = http.createServer(function(req,res) {
// Capture POST call
//if (req.method == 'POST' && req.headers['content-type'].match('application/json')) {
//
// console.log('POST Detected with incoming JSON...');
//
// var body = '';
// req.on('data', function (data) {
// body += data;
// console.log('POST Data: ' + data);
// });
//
// req.on('end', function () {
// console.log('POST Finished and publishing object back to browser...');
// res.writeHead(200, {'Content-Type': 'application/json'});
// res.end(body);
// });
//
//
//
//} else if ((req.method == 'POST' || req.method == 'OPTIONS') && req.headers['content-type'].match('multipart/form-data') > 0) {
console.log('POST Detected with incoming Form-data...');
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log('POST Finished and publishing object back to browser...');
var headers = {};
headers['Content-Type'] = 'application/json';
headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = true;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Access-Control-Allow-Origin, Content-Type, Accept";
res.writeHead(200, headers);
var output = {};
_.extend(output, unflatten(fields));
if (_.isEmpty(files)) return res.end(JSON.stringify(output));
for (var i in files) {
if (files.hasOwnProperty(i)) {
output[i] = {};
fs.readFile(files[i].path, function (err, data) {
output[i].type = files[i].type;
output[i].size = files[i].size;
output[i].name = files[i].name;
output[i].lastModifiedDate = files[i].lastModifiedDate;
output[i].data = 'data:' + files[i].type + ';base64,' + data.toString('base64');
res.end(JSON.stringify(output));
});
}
}
});
//} else {
// console.log('GET Detected...');
// console.log('GET Returning OK');
// res.writeHead(200, {'Content-Type': 'text/html'})
// res.end('OK');
//}
});
server.listen(options.port, options.host);
console.log("listening on " + options.host + ':' + options.port);

View File

@ -1,48 +0,0 @@
<?php
// Parse as Form Data
$passthrough = $_REQUEST;
// Parse as JSON API Request
foreach (getallheaders() as $name => $value) {
if (strpos(strtolower($name), 'content-type') > -1
&& strpos(strtolower($value), 'json') > -1) {
$json = file_get_contents('php://input');
$obj = json_decode($json);
foreach ($obj as $key => $value) {
$passthrough[$key] = $value;
}
break;
}
}
$model = array(
'from' => $passthrough['from'],
'subject' => $passthrough['subject'],
'body' => $passthrough['body'],
'nestedObject' => array(
'nest' => $passthrough["nestedObject_nest"]
)
);
$fileName = $_FILES['fileAttachment']['name'];
$fileType = $_FILES['fileAttachment']['type'];
if ($_FILES['fileAttachment']['tmp_name'] != "") {
$fileContent = file_get_contents($_FILES['fileAttachment']['tmp_name']);
$dataUrl = 'data:' . $fileType . ';base64,' . base64_encode($fileContent);
$model['fileAttachment'] = array(
'name' => $fileName,
'type' => $fileType,
'data' => $dataUrl
);
}
echo json_encode($model);
?>