├── .editorconfig ├── .ember-cli ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .template-lintrc.js ├── .travis.yml ├── .watchmanconfig ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep └── mixins │ └── form-data-adapter.js ├── app ├── .gitkeep └── transforms │ └── file.js ├── config ├── ember-try.js └── environment.js ├── ember-cli-build.js ├── index.js ├── package-lock.json ├── package.json ├── testem.js ├── tests ├── dummy │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ └── .gitkeep │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── application.hbs │ │ │ └── components │ │ │ └── .gitkeep │ ├── config │ │ ├── environment.js │ │ ├── optional-features.json │ │ └── targets.js │ └── public │ │ └── robots.txt ├── helpers │ └── .gitkeep ├── index.html ├── integration │ └── .gitkeep ├── test-helper.js └── unit │ ├── .gitkeep │ ├── mixins │ └── form-data-adapter-test.js │ └── transforms │ └── file-test.js └── vendor └── .gitkeep /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | /node_modules/ 12 | 13 | # misc 14 | /coverage/ 15 | !.* 16 | 17 | # ember-try 18 | /.node_modules.ember-try/ 19 | /bower.json.ember-try 20 | /package.json.ember-try 21 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2017, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | }, 19 | overrides: [ 20 | // node files 21 | { 22 | files: [ 23 | '.eslintrc.js', 24 | '.template-lintrc.js', 25 | 'ember-cli-build.js', 26 | 'index.js', 27 | 'testem.js', 28 | 'blueprints/*/index.js', 29 | 'config/**/*.js', 30 | 'tests/dummy/config/**/*.js' 31 | ], 32 | excludedFiles: [ 33 | 'addon/**', 34 | 'addon-test-support/**', 35 | 'app/**', 36 | 'tests/dummy/app/**' 37 | ], 38 | parserOptions: { 39 | sourceType: 'script', 40 | ecmaVersion: 2015 41 | }, 42 | env: { 43 | browser: false, 44 | node: true 45 | }, 46 | plugins: ['node'], 47 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 48 | // add your custom rules and overrides for node files here 49 | }) 50 | } 51 | ] 52 | }; 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist/ 5 | /tmp/ 6 | 7 | # dependencies 8 | /bower_components/ 9 | /node_modules/ 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/ 15 | /libpeerconnection.log 16 | /npm-debug.log* 17 | /testem.log 18 | /yarn-error.log 19 | /yarn.lock 20 | 21 | # ember-try 22 | /.node_modules.ember-try/ 23 | /bower.json.ember-try 24 | /package.json.ember-try 25 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /bower_components/ 7 | 8 | # misc 9 | /.bowerrc 10 | /.editorconfig 11 | /.ember-cli 12 | /.eslintignore 13 | /.eslintrc.js 14 | /.gitignore 15 | /.template-lintrc.js 16 | /.travis.yml 17 | /.watchmanconfig 18 | /bower.json 19 | /config/ember-try.js 20 | /ember-cli-build.js 21 | /testem.js 22 | /tests/ 23 | /yarn.lock 24 | .gitkeep 25 | 26 | # ember-try 27 | /.node_modules.ember-try/ 28 | /bower.json.ember-try 29 | /package.json.ember-try 30 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'recommended' 5 | }; 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "6" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | directories: 16 | - $HOME/.npm 17 | 18 | env: 19 | global: 20 | # See https://git.io/vdao3 for details. 21 | - JOBS=1 22 | 23 | jobs: 24 | fail_fast: true 25 | allow_failures: 26 | - env: EMBER_TRY_SCENARIO=ember-canary 27 | 28 | include: 29 | # runs linting and tests with current locked deps 30 | 31 | - stage: "Tests" 32 | name: "Tests" 33 | script: 34 | - npm run lint:hbs 35 | - npm run lint:js 36 | - npm test 37 | 38 | # we recommend new addons test the current and previous LTS 39 | # as well as latest stable release (bonus points to beta/canary) 40 | - stage: "Additional Tests" 41 | env: EMBER_TRY_SCENARIO=ember-lts-2.16 42 | - env: EMBER_TRY_SCENARIO=ember-lts-2.18 43 | - env: EMBER_TRY_SCENARIO=ember-release 44 | - env: EMBER_TRY_SCENARIO=ember-beta 45 | - env: EMBER_TRY_SCENARIO=ember-canary 46 | - env: EMBER_TRY_SCENARIO=ember-default-with-jquery 47 | 48 | before_install: 49 | - npm config set spin false 50 | - npm install -g npm@4 51 | - npm --version 52 | 53 | script: 54 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO 55 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-cli-form-data 2 | 3 | This Ember-CLI addon adds file uploads through FormData to the Ember Data 4 | 5 | ### Install 6 | 7 | ``` 8 | ember install ember-cli-form-data 9 | ``` 10 | 11 | ### Usage 12 | 13 | Add a file field on the model 14 | 15 | ```js 16 | // models/post.js 17 | 18 | export default DS.Model.extend({ 19 | attachment: DS.attr('file'), 20 | ... 21 | }); 22 | ``` 23 | 24 | Add the FormDataMixin to your post adapter. Run ``ember g adapter post`` if you don't have the adapter. 25 | 26 | ```js 27 | // adapters/post.js 28 | 29 | import FormDataAdapterMixin from 'ember-cli-form-data/mixins/form-data-adapter'; 30 | 31 | export default ApplicationAdapter.extend(FormDataAdapterMixin, { 32 | // Adapter code 33 | }); 34 | ``` 35 | 36 | Then you can use an ```` to send the attachment: 37 | 38 | ```js 39 | var file = document.getElementById('file-field').files[0]; 40 | model.set('attachment', file); 41 | model.save(); 42 | ``` 43 | 44 | This will send the ``attachment`` and all other attributes as a FormData object. 45 | 46 | 47 | ### Flatten FormData fields 48 | 49 | Some api's desire the form data fields to not include the root object 50 | name. For example, the default adapter behavior would result in ``post[title]`` 51 | in your serialized data. If your api instead expects just ``title``, 52 | add ``disableRoot: true`` to remove the model name from the fields. 53 | 54 | ### Other Resources 55 | 56 | * [EmberScreencasts video on using ember-cli-form-data](https://www.emberscreencasts.com/posts/48-upload-a-file-as-part-of-a-form) 57 | 58 | ### Thanks 59 | 60 | This addon was inspired by Matt Beedle's blog post http://blog.mattbeedle.name/posts/file-uploads-in-ember-data/ 61 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/addon/.gitkeep -------------------------------------------------------------------------------- /addon/mixins/form-data-adapter.js: -------------------------------------------------------------------------------- 1 | import Mixin from '@ember/object/mixin'; 2 | import { isArray } from '@ember/array'; 3 | 4 | export default Mixin.create({ 5 | // Overwrite to change the request types on which Form Data is sent 6 | formDataTypes: ['POST', 'PUT', 'PATCH'], 7 | 8 | // Overwrite to flatten the form data by removing the root 9 | disableRoot: false, 10 | 11 | ajaxOptions: function(url, type, options) { 12 | var data; 13 | 14 | if (options && 'data' in options) { data = options.data; } 15 | 16 | var hash = this._super.apply(this, arguments); 17 | 18 | if (typeof FormData !== 'undefined' && data && this.formDataTypes.indexOf(type) >= 0) { 19 | hash.processData = false; 20 | hash.contentType = false; 21 | if (typeof hash.headers !== 'undefined') { 22 | delete hash.headers['content-type']; 23 | } 24 | hash.data = this._getFormData(data); 25 | } 26 | 27 | return hash; 28 | }, 29 | 30 | _getFormData: function(data) { 31 | var formData = new FormData(); 32 | if (this.get('disableRoot')) { 33 | var root = Object.keys(data)[0]; 34 | Object.keys(data[root]).forEach(function(key) { 35 | this._appendValue(data[root][key], key, formData); 36 | }, this); 37 | } else { 38 | // Handle >1 root key: 39 | Object.keys(data).forEach(function(root) { 40 | this._appendValue(data[root], root, formData); 41 | }, this); 42 | } 43 | 44 | return formData; 45 | }, 46 | 47 | _appendValue(value, formKey, formData) { 48 | if (isArray(value)) { 49 | value.forEach(function(item) { 50 | this._appendValue(item, `${formKey}[]`, formData); 51 | }, this); 52 | } else if (value && value.constructor === Object) { 53 | Object.keys(value).forEach(function(key) { 54 | this._appendValue(value[key], `${formKey}[${key}]`, formData); 55 | }, this); 56 | } else if (typeof value !== 'undefined'){ 57 | formData.append(formKey, value === null ? '' : value); 58 | } 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/app/.gitkeep -------------------------------------------------------------------------------- /app/transforms/file.js: -------------------------------------------------------------------------------- 1 | import Transform from 'ember-data/transform'; 2 | 3 | export default Transform.extend({ 4 | deserialize: function(serialized) { 5 | return serialized; 6 | }, 7 | 8 | serialize: function(deserialized) { 9 | return deserialized; 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | useYarn: true, 13 | scenarios: [ 14 | { 15 | name: 'ember-lts-2.16', 16 | env: { 17 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }) 18 | }, 19 | npm: { 20 | devDependencies: { 21 | '@ember/jquery': '^0.5.1', 22 | 'ember-source': '~2.16.0' 23 | } 24 | } 25 | }, 26 | { 27 | name: 'ember-lts-2.18', 28 | env: { 29 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }) 30 | }, 31 | npm: { 32 | devDependencies: { 33 | '@ember/jquery': '^0.5.1', 34 | 'ember-source': '~2.18.0' 35 | } 36 | } 37 | }, 38 | { 39 | name: 'ember-release', 40 | npm: { 41 | devDependencies: { 42 | 'ember-source': urls[0] 43 | } 44 | } 45 | }, 46 | { 47 | name: 'ember-beta', 48 | npm: { 49 | devDependencies: { 50 | 'ember-source': urls[1] 51 | } 52 | } 53 | }, 54 | { 55 | name: 'ember-canary', 56 | npm: { 57 | devDependencies: { 58 | 'ember-source': urls[2] 59 | } 60 | } 61 | }, 62 | { 63 | name: 'ember-default', 64 | npm: { 65 | devDependencies: {} 66 | } 67 | }, 68 | { 69 | name: 'ember-default-with-jquery', 70 | env: { 71 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 72 | 'jquery-integration': true 73 | }) 74 | }, 75 | npm: { 76 | devDependencies: { 77 | '@ember/jquery': '^0.5.1' 78 | } 79 | } 80 | } 81 | ] 82 | }; 83 | }); 84 | }; 85 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function(defaults) { 6 | let app = new EmberAddon(defaults, { 7 | // Add options here 8 | }); 9 | 10 | /* 11 | This build file specifies the options for the dummy test app of this 12 | addon, located in `/tests/dummy` 13 | This build file does *not* influence how the addon or the app using it 14 | behave. You most likely want to be modifying `./index.js` or app's build file 15 | */ 16 | 17 | return app.toTree(); 18 | }; 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: require('./package').name 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-form-data", 3 | "version": "2.1.2", 4 | "description": "Ember-CLI addon that adds FormData file upload to the RESTAdapter", 5 | "keywords": [ 6 | "ember-addon", 7 | "FormData" 8 | ], 9 | "repository": "https://github.com/funtusov/ember-cli-form-data", 10 | "license": "MIT", 11 | "author": "", 12 | "directories": { 13 | "doc": "doc", 14 | "test": "tests" 15 | }, 16 | "scripts": { 17 | "build": "ember build", 18 | "lint:hbs": "ember-template-lint .", 19 | "lint:js": "eslint .", 20 | "start": "ember serve", 21 | "test": "ember test", 22 | "test:all": "ember try:each" 23 | }, 24 | "dependencies": { 25 | "ember-cli-babel": "^7.26.6" 26 | }, 27 | "devDependencies": { 28 | "@ember/optional-features": "^0.6.3", 29 | "broccoli-asset-rev": "^2.7.0", 30 | "ember-ajax": "^3.1.0", 31 | "ember-cli": "~3.5.1", 32 | "ember-cli-dependency-checker": "^3.0.0", 33 | "ember-cli-eslint": "^4.2.3", 34 | "ember-cli-htmlbars": "^3.0.0", 35 | "ember-cli-htmlbars-inline-precompile": "^1.0.3", 36 | "ember-cli-inject-live-reload": "^1.8.2", 37 | "ember-cli-sri": "^2.1.1", 38 | "ember-cli-template-lint": "^1.0.0-beta.1", 39 | "ember-cli-uglify": "^2.1.0", 40 | "ember-data": "~3.5.0", 41 | "ember-disable-prototype-extensions": "^1.1.3", 42 | "ember-export-application-global": "^2.0.0", 43 | "ember-load-initializers": "^1.1.0", 44 | "ember-maybe-import-regenerator": "^0.1.6", 45 | "ember-qunit": "^3.4.1", 46 | "ember-resolver": "^5.0.1", 47 | "ember-source": "~3.5.1", 48 | "ember-source-channel-url": "^1.1.0", 49 | "ember-try": "^1.0.0", 50 | "eslint-plugin-ember": "^5.2.0", 51 | "eslint-plugin-node": "^7.0.1", 52 | "loader.js": "^4.7.0", 53 | "qunit-dom": "^0.8.0" 54 | }, 55 | "engines": { 56 | "node": "6.* || 8.* || >= 10.*" 57 | }, 58 | "ember-addon": { 59 | "configPath": "tests/dummy/config" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | }); 11 | 12 | export default Router; 13 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/styles/app.css -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Welcome to Ember

2 | 3 | {{outlet}} -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | } 24 | }; 25 | 26 | if (environment === 'development') { 27 | // ENV.APP.LOG_RESOLVER = true; 28 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 29 | // ENV.APP.LOG_TRANSITIONS = true; 30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 31 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 32 | } 33 | 34 | if (environment === 'test') { 35 | // Testem prefers this... 36 | ENV.locationType = 'none'; 37 | 38 | // keep test console output quieter 39 | ENV.APP.LOG_ACTIVE_GENERATION = false; 40 | ENV.APP.LOG_VIEW_LOOKUPS = false; 41 | 42 | ENV.APP.rootElement = '#ember-testing'; 43 | ENV.APP.autoboot = false; 44 | } 45 | 46 | if (environment === 'production') { 47 | // here you can enable a production-specific feature 48 | } 49 | 50 | return ENV; 51 | }; 52 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": false 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/integration/.gitkeep -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/mixins/form-data-adapter-test.js: -------------------------------------------------------------------------------- 1 | import Object from '@ember/object'; 2 | import { module, test } from 'qunit'; 3 | 4 | import FormDataAdapterMixin from 'ember-cli-form-data/mixins/form-data-adapter'; 5 | 6 | var adapter; 7 | 8 | module('FormDataAdapterMixin', function(hooks) { 9 | hooks.beforeEach(function() { 10 | adapter = Object.extend({ 11 | ajaxOptions: function(url, type, options) { 12 | return options; 13 | } 14 | }, FormDataAdapterMixin).create(); 15 | 16 | window.FormData = function() { 17 | this.data = []; 18 | this.append = function(key, value) { 19 | var object = {}; 20 | object[key] = value; 21 | this.data.push(object); 22 | }; 23 | }; 24 | }); 25 | 26 | test('Default FormData Types', function(assert) { 27 | assert.deepEqual(adapter.get('formDataTypes'), ['POST', 'PUT', 'PATCH']); 28 | }); 29 | 30 | test('#ajaxOptions', function(assert) { 31 | var testFormData = new window.FormData(); 32 | 33 | testFormData.append('post[id]', 1); 34 | testFormData.append('post[title]', 'Rails is Omakase'); 35 | 36 | var options = { 37 | data: { 38 | post: { 39 | id: 1, 40 | title: 'Rails is Omakase' 41 | } 42 | } 43 | }; 44 | 45 | var hash = adapter.ajaxOptions('/', 'POST', options); 46 | 47 | assert.deepEqual(hash.data, testFormData); 48 | }); 49 | 50 | test('Handle nested objects', function(assert) { 51 | var testFormData = new window.FormData(); 52 | var avatarFile = new File([''], 'avatar.jpg'); 53 | 54 | testFormData.append('post[id]', 1); 55 | testFormData.append('post[title]', 'Rails is Omakase'); 56 | testFormData.append('post[author][email]', 'john.doe@doeness'); 57 | testFormData.append('post[author][userData][avatar]', avatarFile); 58 | testFormData.append('post[author][userData][mainName]', 'John Doe'); 59 | testFormData.append('post[author][userData][middleName]', ''); 60 | testFormData.append('post[author][userData][extraNames][]', 'Johnnie Doe'); 61 | testFormData.append('post[author][userData][extraNames][]', 'Johnny Doe'); 62 | 63 | var options = { 64 | data: { 65 | post: { 66 | id: 1, 67 | title: 'Rails is Omakase', 68 | author: { 69 | email: 'john.doe@doeness', 70 | userData: { 71 | avatar: avatarFile, 72 | mainName: 'John Doe', 73 | middleName: null, 74 | extraNames: [ 75 | 'Johnnie Doe', 76 | 'Johnny Doe', 77 | ], 78 | }, 79 | }, 80 | } 81 | } 82 | }; 83 | 84 | var hash = adapter.ajaxOptions('/', 'POST', options); 85 | 86 | assert.deepEqual(hash.data, testFormData); 87 | }); 88 | 89 | test('Handle multiple root objects', function(assert) { 90 | var testFormData = new window.FormData(); 91 | var avatarFile = new File([''], 'avatar.jpg'); 92 | 93 | testFormData.append('post[id]', 1); 94 | testFormData.append('post[title]', 'Rails is Omakase'); 95 | testFormData.append('meta[author][email]', 'john.doe@doeness'); 96 | testFormData.append('meta[author][userData][avatar]', avatarFile); 97 | testFormData.append('meta[author][userData][mainName]', 'John Doe'); 98 | testFormData.append('meta[author][userData][middleName]', ''); 99 | testFormData.append('meta[author][userData][extraNames][]', 'Johnnie Doe'); 100 | testFormData.append('meta[author][userData][extraNames][]', 'Johnny Doe'); 101 | 102 | var options = { 103 | data: { 104 | post: { 105 | id: 1, 106 | title: 'Rails is Omakase' 107 | }, 108 | meta: { 109 | author: { 110 | email: 'john.doe@doeness', 111 | userData: { 112 | avatar: avatarFile, 113 | mainName: 'John Doe', 114 | middleName: null, 115 | extraNames: [ 116 | 'Johnnie Doe', 117 | 'Johnny Doe', 118 | ], 119 | }, 120 | }, 121 | } 122 | } 123 | }; 124 | 125 | var hash = adapter.ajaxOptions('/', 'POST', options); 126 | 127 | assert.deepEqual(hash.data, testFormData); 128 | }); 129 | 130 | test("Don't modify the hash for requests outside formDataTypes", function(assert) { 131 | var options = { 132 | data: { 133 | post: { 134 | id: 1, 135 | title: 'Rails is Omakase' 136 | } 137 | } 138 | }; 139 | 140 | var hash = adapter.ajaxOptions('/', 'GET', options); 141 | 142 | assert.deepEqual(hash.data, { 143 | post: { 144 | id: 1, 145 | title: 'Rails is Omakase' 146 | } 147 | }); 148 | }); 149 | 150 | test('Falsey key gets saved', function(assert) { 151 | var testFormData = new window.FormData(); 152 | 153 | testFormData.append('post[preferred]', false); 154 | 155 | var options = { 156 | data: { 157 | post: { 158 | preferred: false 159 | } 160 | } 161 | }; 162 | 163 | var hash = adapter.ajaxOptions('/', 'POST', options); 164 | 165 | assert.deepEqual(hash.data, testFormData); 166 | }); 167 | 168 | test('Null key as empty string', function(assert) { 169 | var testFormData = new window.FormData(); 170 | 171 | testFormData.append('post[title]', ''); 172 | 173 | var options = { 174 | data: { 175 | post: { 176 | title: null 177 | } 178 | } 179 | }; 180 | 181 | var hash = adapter.ajaxOptions('/', 'POST', options); 182 | 183 | assert.deepEqual(hash.data, testFormData); 184 | }); 185 | 186 | test('Default disableRoot', function(assert) { 187 | assert.deepEqual(adapter.get('disableRoot'), false); 188 | }); 189 | 190 | test('#ajaxOptions should exclude root when disableRoot is true', function(assert) { 191 | var testFormData = new window.FormData(); 192 | 193 | // Setup expected form data; note the lack of the 'post' root (post[id]) 194 | testFormData.append('id', 1); 195 | testFormData.append('title', 'Rails is Omakase'); 196 | 197 | var options = { 198 | data: { 199 | post: { 200 | id: 1, 201 | title: 'Rails is Omakase' 202 | } 203 | } 204 | }; 205 | 206 | adapter.set('disableRoot', true); 207 | 208 | var hash = adapter.ajaxOptions('/', 'POST', options); 209 | 210 | assert.deepEqual(hash.data, testFormData); 211 | }); 212 | }); 213 | -------------------------------------------------------------------------------- /tests/unit/transforms/file-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { setupTest } from 'ember-qunit'; 3 | 4 | module('FileTransform', function(hooks) { 5 | setupTest(hooks); 6 | 7 | // Replace this with your real tests. 8 | test('it exists', function(assert) { 9 | var transform = this.owner.lookup('transform:file'); 10 | assert.ok(transform); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funtusov/ember-cli-form-data/7fe17be1e5c27d2c32d8d71882002a5eca09bef1/vendor/.gitkeep --------------------------------------------------------------------------------