diff --git a/.gitignore b/.gitignore
index 79787e35..e8a68eb0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ results
lib
node_modules
components
+coverage
bower_components
npm-debug.log
.idea
diff --git a/.travis.yml b/.travis.yml
index ad563755..20b0f596 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,11 @@
language: node_js
node_js:
- - "0.10"
+ - "7.0"
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- 'npm install -g bower grunt-cli'
- 'bower install --config.interactive=false'
+
+script: grunt travis
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef816d33..b768c53e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,36 @@
-# Unreleased
+
+## 1.6.1 (2017-01-06)
+### Bug fixes
-# 1.6.0 (2016-12-25)
+* fix(copy) Collections are now copied/cloned properly ([c92b138](https://github.com/mgonto/restangular/commit/c92b138))
+* fix(copy) Copying collections now correctly sets route, fromServer and parent on the copy ([7fd668b](https://github.com/mgonto/restangular/commit/7fd668b))
+* fix(elementTransformer) matchTransformer now doesn't throw if route is undefined ([fb242ae](https://github.com/mgonto/restangular/commit/fb242ae))
+
+### Docs
+
+* chore(docs): update contribution guidelines ([c49ca45](https://github.com/mgonto/restangular/commit/c49ca45))
+* fix(docs): add link to david-dm.org from badge ([2bfb745](https://github.com/mgonto/restangular/commit/2bfb745))
+* chore(docs) Add new example production site ([2596035](https://github.com/mgonto/restangular/commit/2596035))
+* chore(docs) Add note about pull requests and github preview tab ([6883075](https://github.com/mgonto/restangular/commit/6883075))
+* chore(docs) Apply automatic formatting to code and spec ([bc16122](https://github.com/mgonto/restangular/commit/bc16122))
+* chore(docs) Reformat changelog, add unreleased section ([8bfa685](https://github.com/mgonto/restangular/commit/8bfa685))
+* chore(docs) Update issue guidelines to include StackOverflow as source for solutions to problems ([34b0e9a](https://github.com/mgonto/restangular/commit/34b0e9a))
+* chore(docs) Update link to demo Plunker, rephrase ([7c30615](https://github.com/mgonto/restangular/commit/7c30615))
+* chore(test) fix jshint errors in spec file ([1a988cb](https://github.com/mgonto/restangular/commit/1a988cb))
+* feat(docs) Add FAQ about cancelling request ([8552c51](https://github.com/mgonto/restangular/commit/8552c51)), closes [#926](https://github.com/mgonto/restangular/issues/926) [#1145](https://github.com/mgonto/restangular/issues/1145) [#1377](https://github.com/mgonto/restangular/issues/1377) [#1391](https://github.com/mgonto/restangular/issues/1391)
+
+### Other
+
+* chore(changelog): upgrade package and config ([58caacd](https://github.com/mgonto/restangular/commit/58caacd))
+* chore(dependencies): Update lodash version to ~4.17.0 as in unit tests ([e0b68a0](https://github.com/mgonto/restangular/commit/e0b68a0))
+* chore(deps): upgrade dev dependencies, fix tests (#1450) ([b583197](https://github.com/mgonto/restangular/commit/b583197)), closes [#1450](https://github.com/mgonto/restangular/issues/1450)
+* chore(travis): change travis script and include coveralls ([ca9856a](https://github.com/mgonto/restangular/commit/ca9856a))
+* test(coverage): add coverage and coveralls.io integration ([fdd5de6](https://github.com/mgonto/restangular/commit/fdd5de6))
+* Update dist files ([7c245a2](https://github.com/mgonto/restangular/commit/7c245a2))
+
+
+## 1.6.0 (2016-12-25)
* Url now supports unescaped suffix (0350bcd)
* Added Restangular Plunkr example (c4ef002)
@@ -23,11 +52,13 @@
* Added context/explanation of when to use JSONP. (fec9b27)
* Add regexp matching for route to element transformers (#1430) (de8f561)
-# 1.5.2 (2016-02-15)
+
+## 1.5.2 (2016-02-15)
* Change \_.contains to \_.includes for compatability with lodash >= 4.0
-# 1.5.1 (2015-04-03)
+
+## 1.5.1 (2015-04-03)
* Release 1.5.0
* Updated zip
@@ -39,7 +70,8 @@
* Update README.md
* Update README.md
-# 1.5.0 (2015-04-03)
+
+## 1.5.0 (2015-04-03)
* Tons of bug fixes
* Upgraded Lodash to 1.3.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9722aac4..59451f29 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,42 +1,67 @@
-#Issues
+# Issues
-## Opening an Issue
+Read the [issue guidlines](.github/ISSUE_TEMPLATE.md) before opening an issue!
-To open an issue, please keep in mind a few important things. First, take a look at the README docs and make sure that your question isn't already answered in the documentation. In particular, review [the configuration methods](https://github.com/mgonto/restangular#configuring-restangular) and [methods description](https://github.com/mgonto/restangular#methods-description). Then make sure you search the issues list to see if there's already an issue open that solves your problem. Then, once you've determined that your issue isn't a duplicate, here a couple guidelines to opening an issue that will be addressed easily and quickly:
+# How to submit PRs
-- Please make sure your issue is written in a clear and succint manner, so that all the details of your issue are easy to understand and fully explained. Also, please make sure enclose your code in [fenced blocks](https://help.github.com/articles/creating-and-highlighting-code-blocks/) for readability.
-- Make sure your issue includes a live Plunker (fork [this Plunker](http://plnkr.co/edit/26Heuv5F6hUgxpNWNTee?p=info)), and all relevant code samples (as well as information about server responses, if relevant)
+## Install env
-# PRs
-
-##Install env
-
-In order to contribute just git clone the repository and then run:
+In order to contribute just create your own [fork](https://help.github.com/articles/fork-a-repo/)
+of the repository and then run:
```
-git clone git@github.com:mgonto/restangular.git
+git clone git@github.com:/restangular.git
cd restangular
npm install grunt-cli --global
npm install
```
-Be sure to have PhantomJS installed as Karma tests use it. Otherwise, in Mac just run
+## Create a branch
-```
-brew install phantomjs
-```
+Create a branch for your code changes
-All changes must be done in src/restangular.js
+`git checkout -b my_awesome_fix`
-##Branching
+## Write tests
-Please submit a Pull Request or create issues for anything you want :). If your code is super small, nobody will blame
-you for doing it from master to master. Otherwise, please try to create a branch `features/[name of your awesome feature]`.
+When making changes to the code, please always **write a test case** for
+your topic before making the change. Watch the test fail, then
+implement the change and watch the test succeed.
-##Testing and styling
+Tests are run with `grunt test`.
-Before submitting any PR, you should run `grunt test` to validate your didn't break anything. If you just added a new
-feature, please also add tests for it. And when you're done with your code, run `grunt jshint` to check
+## Keep the style
+
+When you're done with your code, run `grunt jshint` to check
if you code follow the same simple coding design as the rest of the project.
+Consider integrating `jshint` in your editor to get real time feedback on your
+style as you're coding.
+
+## Commit message format
+
+Please write your commit messages in the [angular conventional changelog](https://github.com/conventional-changelog/conventional-changelog-angular/blob/master/convention.md) format. This will help
+us to keep a decent [CHANGELOG](CHANGELOG.md) with minimum effort. Check previous commit
+messages for examples.
+
+## Update docs
+
+If your code change includes new features, please include an update to the [README.md](README.md)
+explaining your feature.
+
+**Don't**, however, generate distribution files (the files in [dist](dist)). This will be done
+on a regular basis by maintainers as PRs are merged.
+
+## Squash commits
+
+Please consider squasing the commits in your topic branch into a single commit including
+all changes needed. This will make the PR cleaner and the change history more easy to follow
+after the PR has been merged. Also, the CHANGELOG will make more sense.
+
+Look [here](https://ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one/) and
+[here](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Squashing-Commits) for how to.
+
+## Sumbit the PR
+
+Now you're ready to [open a PR](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
Thanks!
diff --git a/Gruntfile.js b/Gruntfile.js
index d06566eb..13420589 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -85,9 +85,45 @@ module.exports = function(grunt) {
autoWatch: true
}
},
- changelog: {
+ coveralls: {
+ // Options relevant to all targets
options: {
- dest: 'CHANGELOG.md'
+ // When true, grunt-coveralls will only print a warning rather than
+ // an error, to prevent CI builds from failing unnecessarily (e.g. if
+ // coveralls.io is down). Optional, defaults to false.
+ force: false
+ },
+
+ restangular: {
+ // LCOV coverage file (can be string, glob or array)
+ src: 'coverage/**/lcov.info',
+ options: {
+ // Any options for just this target
+ }
+ },
+ },
+ conventionalChangelog: {
+ options: {
+ changelogOpts: {
+ // conventional-changelog options go here
+ outputUnreleased: true,
+ // preset: 'angular'
+ },
+ context: {
+ // context goes here
+ },
+ gitRawCommitsOpts: {
+ // git-raw-commits options go here
+ },
+ parserOpts: {
+ // conventional-commits-parser options go here
+ },
+ writerOpts: {
+ // conventional-changelog-writer options go here
+ }
+ },
+ release: {
+ src: 'CHANGELOG.md'
}
}
});
@@ -111,6 +147,8 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-zip');
+ grunt.loadNpmTasks('grunt-coveralls');
+
// Default task.
grunt.registerTask('default', ['build']);
@@ -122,7 +160,9 @@ module.exports = function(grunt) {
grunt.registerTask('test-debug', ['karma:debug']);
- grunt.registerTask('travis', ['karma:travis', 'karma:travisUnderscore']);
+ grunt.registerTask('travis', ['karma:travis', 'karma:travisUnderscore', 'coveralls']);
+
+ grunt.registerTask('changelog', ['conventionalChangelog']);
// Provides the "bump" task.
grunt.registerTask('bump', 'Increment version number', function() {
diff --git a/MAINTENANCE.md b/MAINTENANCE.md
new file mode 100644
index 00000000..6d219897
--- /dev/null
+++ b/MAINTENANCE.md
@@ -0,0 +1,45 @@
+# Restangular maintenance policy
+
+Restangular follows the [Semantic Versioning](http://semver.org/) for its releases:
+`(Major).(Minor).(Patch)`.
+
+- **Patch number**: When backwards compatible bug fixes are introduced that fix
+ incorrect behavior.
+- **Minor version**: When new, backwards compatible functionality is introduced
+ to the public API or a minor feature is introduced, or when a set of smaller
+ features is rolled out.
+- **Major version**: Whenever there is something significant or any backwards
+ incompatible changes are introduced to the public API.
+
+The current stable release will receive security patches and bug fixes
+(eg. `1.6.0` -> `1.6.1`). Feature releases will mark the next supported stable
+release where the minor version is increased numerically by increments of one
+(eg. `1.6.3 -> 1.7.0`).
+
+We encourage everyone to run the latest stable release.
+
+# Notes for maintainers
+
+Following are a set of guidelines and checklists for maintaining the
+[main repository](https://github.com/mgonto/restangular).
+
+## Keeping master usable
+
+In order for developers to use the bleeding edge master version in their projects,
+we'll need to keep the dist files up to date. After merging PRs that include mentionable
+changes, please update the dist files `grunt build` and the CHANGELOG `grunt changelog`.
+The CHANGELOG will have a section called `Unreleased` for changes not yet included in
+any release. This is the place for
+
+## Releasing
+
+Follow this checklist for publishing a new release.
+
+- [ ] Bump version `grunt bump --type=patch/minor/major`
+- [ ] Create changelog `grunt changelog` (open it in editor and make sure its sensible)
+- [ ] Make dist files `grunt build`
+- [ ] Commit changes `git add dist package.json CHANGELOG.md` and `git commit -m "chore(release): release 1.6.1"`
+- [ ] Tag release `git tag -a -m "Version 1.6.1" 1.6.1`
+- [ ] Push everything `git push` and `git push --tags`
+- [ ] Publish to NPM `npm publish`
+- [ ] Create a [new release](https://github.com/mgonto/restangular/releases) on GitHub, entering the version changelog as body
diff --git a/README.md b/README.md
index 359bf272..aea15823 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,23 @@
-#Restangular
+# Restangular
[](https://travis-ci.org/mgonto/restangular)
+[](https://coveralls.io/github/mgonto/restangular?branch=master)
+[](https://david-dm.org/mgonto/restangular/?type=dev)
+[](https://snyk.io/test/github/mgonto/restangular)
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=martin%40gon%2eto&lc=US&item_name=Martin%20Gontovnikas¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted "Donate once-off to this project using Paypal")
[](https://www.gittip.com/mgonto/)
-Restangular is an AngularJS service that simplifies common GET, POST, DELETE, and UPDATE requests with a minimum of client code.
-It's a perfect fit for any WebApp that consumes data from a RESTful API.
+Restangular is an AngularJS service that simplifies common GET, POST, DELETE, and UPDATE requests with a minimum of client code. It's a perfect fit for any WebApp that consumes data from a RESTful API.
-Try the [live demo on plunkr](http://plnkr.co/edit/8qrGeE?p=preview). It uses the same example as the official [Angular Javascript Project](http://angularjs.org/#wire-up-a-backend), but with Restangular!
+**Note This version of Restangular [only supports Angular 1](#supported-angular-versions). For an Angular 2+ version of Restangular, check out [ngx-restangular](https://github.com/2muchcoffeecom/ngx-restangular).** It's a separate project with different maintainers, so issues regarding ngx-restangular should be reported [over there](https://github.com/2muchcoffeecom/ngx-restangular/issues) :wink:
-Watch [a video introduction of a talk I gave at Devoxx France](http://www.parleys.com/play/535a189ee4b0c5ba17d43455/chapter1/about) about Restangular.
+Learn Restangular! Try the [live demo on plunkr](http://plnkr.co/edit/8qrGeE?p=preview). It uses the same example as the official [Angular Javascript Project](http://angularjs.org/#wire-up-a-backend), but with Restangular! Or watch [a video introduction of a talk I gave at Devoxx France](http://www.parleys.com/play/535a189ee4b0c5ba17d43455/chapter1/about) about Restangular.
-#Table of contents
+
+# Table of contents
- [Restangular](#restangular)
- [Differences with $resource](#differences-with-resource)
@@ -135,7 +138,7 @@ $scope.user.one('messages', 123).one('from', 123).getList('unread');
**[Back to top](#table-of-contents)**
-#How do I add this to my project?
+## How do I add this to my project?
You can download this by:
@@ -152,7 +155,7 @@ You can download this by:
**[Back to top](#table-of-contents)**
-#Dependencies
+## Dependencies
Restangular depends on Angular and Lodash (or Underscore).
@@ -165,11 +168,12 @@ Each time, there're more Production WebApps using `Restangular`. If your webapp
* **Life360** is using Restangular to build the WebApp version of their platform
* **Thomson Reuters** is using Restangular for the new Webapp they've built
* **Quran.com** is using Restangular for their alpha/beta app and soon to be main site
+* **[Worldcampus.co](http://www.worldcampus.co)** is using Restangular for their beta international students social network.
* **[ENTSO-E Transparency Platform](https://transparency.entsoe.eu)**
**[Back to top](#table-of-contents)**
-#Starter Guide
+# Starter Guide
## Quick Configuration (For Lazy Readers)
This is all you need to start using all the basic Restangular features.
diff --git a/dist/restangular.js b/dist/restangular.js
index f014fd39..b59b25f9 100644
--- a/dist/restangular.js
+++ b/dist/restangular.js
@@ -1,6 +1,6 @@
/**
* Restful Resources service for AngularJS apps
- * @version v1.6.0 - 2017-01-05 * @link https://github.com/mgonto/restangular
+ * @version v1.6.1 - 2017-01-06 * @link https://github.com/mgonto/restangular
* @author Martin Gontovnikas
* @license MIT License, http://www.opensource.org/licenses/MIT
*/(function(root, factory) {
diff --git a/dist/restangular.min.js b/dist/restangular.min.js
index 67d3cfc0..729f8aad 100644
--- a/dist/restangular.min.js
+++ b/dist/restangular.min.js
@@ -1,6 +1,6 @@
/**
* Restful Resources service for AngularJS apps
- * @version v1.6.0 - 2017-01-05 * @link https://github.com/mgonto/restangular
+ * @version v1.6.1 - 2017-01-06 * @link https://github.com/mgonto/restangular
* @author Martin Gontovnikas
* @license MIT License, http://www.opensource.org/licenses/MIT
*/!function(a,b){"function"==typeof define&&define.amd?define(["lodash","angular"],b):"object"==typeof module&&module.exports?module.exports=b(require("lodash"),require("angular")):b(a._,a.angular)}(this,function(a,b){var c=b.module("restangular",[]);return c.provider("Restangular",function(){var c={};c.init=function(c,d){function e(b,c,d,e){var f={};return a.each(a.keys(e),function(g){var h=e[g];h.params=a.extend({},h.params,b.defaultRequestParams[h.method.toLowerCase()]),a.isEmpty(h.params)&&delete h.params,b.isSafe(h.method)?f[g]=function(){return c(a.extend(h,{url:d}))}:f[g]=function(b){return c(a.extend(h,{url:d,data:b}))}}),f}c.configuration=d;var f=["get","head","options","trace","getlist"];d.isSafe=function(b){return a.includes(f,b.toLowerCase())};var g=/^https?:\/\//i;d.isAbsoluteUrl=function(b){return a.isUndefined(d.absoluteUrl)||a.isNull(d.absoluteUrl)?b&&g.test(b):d.absoluteUrl},d.absoluteUrl=!!a.isUndefined(d.absoluteUrl)||d.absoluteUrl,c.setSelfLinkAbsoluteUrl=function(a){d.absoluteUrl=a},d.baseUrl=a.isUndefined(d.baseUrl)?"":d.baseUrl,c.setBaseUrl=function(a){return d.baseUrl=/\/$/.test(a)?a.substring(0,a.length-1):a,this},d.extraFields=d.extraFields||[],c.setExtraFields=function(a){return d.extraFields=a,this},d.defaultHttpFields=d.defaultHttpFields||{},c.setDefaultHttpFields=function(a){return d.defaultHttpFields=a,this},d.plainByDefault=d.plainByDefault||!1,c.setPlainByDefault=function(a){return d.plainByDefault=a===!0,this},d.withHttpValues=function(b,c){return a.defaults(c,b,d.defaultHttpFields)},d.encodeIds=!!a.isUndefined(d.encodeIds)||d.encodeIds,c.setEncodeIds=function(a){d.encodeIds=a},d.defaultRequestParams=d.defaultRequestParams||{get:{},post:{},put:{},remove:{},common:{}},c.setDefaultRequestParams=function(b,c){var e=[],f=c||b;return a.isUndefined(c)?e.push("common"):a.isArray(b)?e=b:e.push(b),a.each(e,function(a){d.defaultRequestParams[a]=f}),this},c.requestParams=d.defaultRequestParams,d.defaultHeaders=d.defaultHeaders||{},c.setDefaultHeaders=function(a){return d.defaultHeaders=a,c.defaultHeaders=d.defaultHeaders,this},c.defaultHeaders=d.defaultHeaders,d.methodOverriders=d.methodOverriders||[],c.setMethodOverriders=function(b){var c=a.extend([],b);return d.isOverridenMethod("delete",c)&&c.push("remove"),d.methodOverriders=c,this},d.jsonp=!a.isUndefined(d.jsonp)&&d.jsonp,c.setJsonp=function(a){d.jsonp=a},d.isOverridenMethod=function(b,c){var e=c||d.methodOverriders;return!a.isUndefined(a.find(e,function(a){return a.toLowerCase()===b.toLowerCase()}))},d.urlCreator=d.urlCreator||"path",c.setUrlCreator=function(b){if(!a.has(d.urlCreatorFactory,b))throw new Error("URL Path selected isn't valid");return d.urlCreator=b,this},d.restangularFields=d.restangularFields||{id:"id",route:"route",parentResource:"parentResource",restangularCollection:"restangularCollection",cannonicalId:"__cannonicalId",etag:"restangularEtag",selfLink:"href",get:"get",getList:"getList",put:"put",post:"post",remove:"remove",head:"head",trace:"trace",options:"options",patch:"patch",getRestangularUrl:"getRestangularUrl",getRequestedUrl:"getRequestedUrl",putElement:"putElement",addRestangularMethod:"addRestangularMethod",getParentList:"getParentList",clone:"clone",ids:"ids",httpConfig:"_$httpConfig",reqParams:"reqParams",one:"one",all:"all",several:"several",oneUrl:"oneUrl",allUrl:"allUrl",customPUT:"customPUT",customPATCH:"customPATCH",customPOST:"customPOST",customDELETE:"customDELETE",customGET:"customGET",customGETLIST:"customGETLIST",customOperation:"customOperation",doPUT:"doPUT",doPATCH:"doPATCH",doPOST:"doPOST",doDELETE:"doDELETE",doGET:"doGET",doGETLIST:"doGETLIST",fromServer:"fromServer",withConfig:"withConfig",withHttpConfig:"withHttpConfig",singleOne:"singleOne",plain:"plain",save:"save",restangularized:"restangularized"},c.setRestangularFields=function(b){return d.restangularFields=a.extend(d.restangularFields,b),this},d.isRestangularized=function(a){return!!a[d.restangularFields.restangularized]},d.setFieldToElem=function(b,c,d){var e=b.split("."),f=c;return a.each(a.initial(e),function(a){f[a]={},f=f[a]}),f[a.last(e)]=d,this},d.getFieldFromElem=function(c,d){var e=c.split("."),f=d;return a.each(e,function(a){f&&(f=f[a])}),b.copy(f)},d.setIdToElem=function(a,b){return d.setFieldToElem(d.restangularFields.id,a,b),this},d.getIdFromElem=function(a){return d.getFieldFromElem(d.restangularFields.id,a)},d.isValidId=function(b){return""!==b&&!a.isUndefined(b)&&!a.isNull(b)},d.setUrlToElem=function(a,b){return d.setFieldToElem(d.restangularFields.selfLink,a,b),this},d.getUrlFromElem=function(a){return d.getFieldFromElem(d.restangularFields.selfLink,a)},d.useCannonicalId=!a.isUndefined(d.useCannonicalId)&&d.useCannonicalId,c.setUseCannonicalId=function(a){return d.useCannonicalId=a,this},d.getCannonicalIdFromElem=function(a){var b=a[d.restangularFields.cannonicalId],c=d.isValidId(b)?b:d.getIdFromElem(a);return c},d.responseInterceptors=d.responseInterceptors||[],d.defaultResponseInterceptor=function(a){return a},d.responseExtractor=function(c,e,f,g,h,i){var j=b.copy(d.responseInterceptors);j.push(d.defaultResponseInterceptor);var k=c;return a.each(j,function(a){k=a(k,e,f,g,h,i)}),k},c.addResponseInterceptor=function(a){return d.responseInterceptors.push(a),this},d.errorInterceptors=d.errorInterceptors||[],c.addErrorInterceptor=function(a){return d.errorInterceptors.push(a),this},c.setResponseInterceptor=c.addResponseInterceptor,c.setResponseExtractor=c.addResponseInterceptor,c.setErrorInterceptor=c.addErrorInterceptor,d.requestInterceptors=d.requestInterceptors||[],d.defaultInterceptor=function(a,b,c,d,e,f,g){return{element:a,headers:e,params:f,httpConfig:g}},d.fullRequestInterceptor=function(c,e,f,g,h,i,j){var k=b.copy(d.requestInterceptors),l=d.defaultInterceptor(c,e,f,g,h,i,j);return a.reduce(k,function(b,c){return a.extend(b,c(b.element,e,f,g,b.headers,b.params,b.httpConfig))},l)},c.addRequestInterceptor=function(a){return d.requestInterceptors.push(function(b,c,d,e,f,g,h){return{headers:f,params:g,element:a(b,c,d,e),httpConfig:h}}),this},c.setRequestInterceptor=c.addRequestInterceptor,c.addFullRequestInterceptor=function(a){return d.requestInterceptors.push(a),this},c.setFullRequestInterceptor=c.addFullRequestInterceptor,d.onBeforeElemRestangularized=d.onBeforeElemRestangularized||function(a){return a},c.setOnBeforeElemRestangularized=function(a){return d.onBeforeElemRestangularized=a,this},c.setRestangularizePromiseInterceptor=function(a){return d.restangularizePromiseInterceptor=a,this},d.onElemRestangularized=d.onElemRestangularized||function(a){return a},c.setOnElemRestangularized=function(a){return d.onElemRestangularized=a,this},d.shouldSaveParent=d.shouldSaveParent||function(){return!0},c.setParentless=function(b){return a.isArray(b)?d.shouldSaveParent=function(c){return!a.includes(b,c)}:a.isBoolean(b)&&(d.shouldSaveParent=function(){return!b}),this},d.suffix=a.isUndefined(d.suffix)?null:d.suffix,c.setRequestSuffix=function(a){return d.suffix=a,this},d.transformers=d.transformers||{},d.matchTransformers=d.matchTransformers||[],c.addElementTransformer=function(b,e,f){var g=null,h=null;2===arguments.length?h=e:(h=f,g=e);var i=function(b,c){return a.isNull(g)||b===g?h(c):c};return a.isRegExp(b)?d.matchTransformers.push({regexp:b,transformer:i}):(d.transformers[b]||(d.transformers[b]=[]),d.transformers[b].push(i)),c},c.extendCollection=function(a,b){return c.addElementTransformer(a,!0,b)},c.extendModel=function(a,b){return c.addElementTransformer(a,!1,b)},d.transformElem=function(b,c,e,f,g){if(!g&&!d.transformLocalElements&&!b[d.restangularFields.fromServer])return b;var h=b,i=d.matchTransformers;i&&a.each(i,function(a){a.regexp.test(e)&&(h=a.transformer(c,h))});var j=d.transformers[e];return j&&a.each(j,function(a){h=a(c,h)}),d.onElemRestangularized(h,c,e,f)},d.transformLocalElements=!a.isUndefined(d.transformLocalElements)&&d.transformLocalElements,c.setTransformOnlyServerElements=function(a){d.transformLocalElements=!a},d.fullResponse=!a.isUndefined(d.fullResponse)&&d.fullResponse,c.setFullResponse=function(a){return d.fullResponse=a,this},d.urlCreatorFactory={};var h=function(){};h.prototype.setConfig=function(a){return this.config=a,this},h.prototype.parentsArray=function(a){for(var b=[];a;)b.push(a),a=a[this.config.restangularFields.parentResource];return b.reverse()},h.prototype.resource=function(b,c,f,g,h,i,j,k){var l=a.defaults(h||{},this.config.defaultRequestParams.common),m=a.defaults(g||{},this.config.defaultHeaders);j&&(d.isSafe(k)?m["If-None-Match"]=j:m["If-Match"]=j);var n=this.base(b);if(i||0===i){var o="";/\/$/.test(n)||(o+="/"),o+=i,n+=o}return this.config.suffix&&n.indexOf(this.config.suffix,n.length-this.config.suffix.length)===-1&&!this.config.getUrlFromElem(b)&&(n+=this.config.suffix),b[this.config.restangularFields.httpConfig]=void 0,e(this.config,c,n,{getList:this.config.withHttpValues(f,{method:"GET",params:l,headers:m}),get:this.config.withHttpValues(f,{method:"GET",params:l,headers:m}),jsonp:this.config.withHttpValues(f,{method:"jsonp",params:l,headers:m}),put:this.config.withHttpValues(f,{method:"PUT",params:l,headers:m}),post:this.config.withHttpValues(f,{method:"POST",params:l,headers:m}),remove:this.config.withHttpValues(f,{method:"DELETE",params:l,headers:m}),head:this.config.withHttpValues(f,{method:"HEAD",params:l,headers:m}),trace:this.config.withHttpValues(f,{method:"TRACE",params:l,headers:m}),options:this.config.withHttpValues(f,{method:"OPTIONS",params:l,headers:m}),patch:this.config.withHttpValues(f,{method:"PATCH",params:l,headers:m})})};var i=function(){};i.prototype=new h,i.prototype.normalizeUrl=function(a){var b=/((?:http[s]?:)?\/\/)?(.*)?/.exec(a);return b[2]=b[2].replace(/[\\\/]+/g,"/"),"undefined"!=typeof b[1]?b[1]+b[2]:b[2]},i.prototype.base=function(b){var c=this;return a.reduce(this.parentsArray(b),function(a,b){var e,f=c.config.getUrlFromElem(b);if(f){if(c.config.isAbsoluteUrl(f))return f;e=f}else if(e=b[c.config.restangularFields.route],b[c.config.restangularFields.restangularCollection]){var g=b[c.config.restangularFields.ids];g&&(e+="/"+g.join(","))}else{var h;h=c.config.useCannonicalId?c.config.getCannonicalIdFromElem(b):c.config.getIdFromElem(b),d.isValidId(h)&&!b.singleOne&&(e+="/"+(c.config.encodeIds?encodeURIComponent(h):h))}return a=a.replace(/\/$/,"")+"/"+e,c.normalizeUrl(a)},this.config.baseUrl)},i.prototype.fetchUrl=function(a,b){var c=this.base(a);return b&&(c+="/"+b),c},i.prototype.fetchRequestedUrl=function(a,c){function e(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b.sort()}function f(a,b,c){for(var d=e(a),f=0;f= 0.1.7",
+ "grunt": "^1.0.0",
+ "grunt-bower": "*",
+ "grunt-bower-task": "*",
+ "grunt-cli": "^1.2.0",
"grunt-contrib-concat": "*",
"grunt-contrib-jshint": "*",
"grunt-contrib-uglify": "*",
- "grunt-bower": "*",
- "grunt-bower-task": "*",
+ "grunt-conventional-changelog": "latest",
+ "grunt-coveralls": "^1.0.1",
"grunt-karma": "latest",
- "grunt-conventional-changelog": "0.0.12",
"grunt-zip": "*",
- "karma": "^0.13.19",
- "karma-chrome-launcher": "~v2.0.0",
+ "jasmine-core": "^2.5.2",
+ "karma": "^1.3.0",
+ "karma-chrome-launcher": "~2.0.0",
+ "karma-coverage": "^1.1.1",
"karma-firefox-launcher": "~v1.0.0",
- "karma-jasmine": "~0.1.5",
- "karma-mocha-reporter": "0.2.8",
+ "karma-jasmine": "^1.1.0",
+ "karma-mocha-reporter": "^2.2.0",
"karma-phantomjs-launcher": "~v1.0.2"
},
"scripts": {
"test": "grunt test --verbose"
},
"license": "MIT"
-}
+}
\ No newline at end of file
diff --git a/src/restangular.js b/src/restangular.js
index 644a2b8b..ff7d5e24 100644
--- a/src/restangular.js
+++ b/src/restangular.js
@@ -989,7 +989,7 @@
_.each(requestMethods, function(requestFunc, name) {
var callOperation = name === 'delete' ? 'remove' : name;
_.each(['do', 'custom'], function(alias) {
- elem[alias + name.toUpperCase()] = _.bind(requestFunc, elem, callOperation);
+ elem[config.restangularFields[alias + name.toUpperCase()]] = _.bind(requestFunc, elem, callOperation);
});
});
elem[config.restangularFields.customGETLIST] = _.bind(fetchFunction, elem);
diff --git a/test/restangularSpec.js b/test/restangularSpec.js
index a6a08221..fd989819 100644
--- a/test/restangularSpec.js
+++ b/test/restangularSpec.js
@@ -1,257 +1,317 @@
-/* global describe, beforeEach, inject, afterEach, it, expect, spyOn, jasmine */
+/* global describe, beforeEach, afterEach, it, expect, spyOn, jasmine */
/* jshint unused: false */
-describe('Restangular', function() {
+describe('Restangular', function () {
// API
- var Restangular, $httpBackend,
- accountsModel, restangularAccounts, restangularAccount0, restangularAccount1,
- infoModel, accountsDoSomethingModel, customers, publications, newCustomer,
- accountsHalModel,
- messages, newAccount, nextAccountId;
+ var Restangular, $httpBackend, testData,
+ restangularAccounts, restangularAccount0, restangularAccount1;
// Load required modules
- beforeEach(angular.mock.module('restangular'));
-
- // Init HTTP mock backend and Restangular resources
- beforeEach(inject(function($injector) {
- // Model
- accountsModel = [{
- id: 0,
- user: 'Martin ',
- amount: 42,
- transactions: []
- }, {
- id: 1,
- user: 'Paul',
- amount: 3.1416,
- transactions: [{
- from: 'Martin',
- amount: 3,
- id: 0
+ beforeEach(function () {
+ // Load restangular module
+ angular.mock.module('restangular');
+
+ // Get references to modules from the injector
+ angular.mock.inject(function ($injector) {
+ $httpBackend = $injector.get('$httpBackend');
+ Restangular = $injector.get('Restangular');
+ });
+
+ // Restangularize a few demo accounts
+ restangularAccounts = Restangular.all('accounts');
+ restangularAccount0 = Restangular.one('accounts', 0);
+ restangularAccount1 = Restangular.one('accounts', 1);
+
+ // Create testdata for our tests
+ testData = {
+ // Model
+ accountsModel: [{
+ id: 0,
+ user: 'Martin ',
+ amount: 42,
+ transactions: []
}, {
- from: 'Anonymous',
- amount: 0.1416,
- id: 1
- }]
- }];
- nextAccountId = 22;
-
- // HAL model (http://stateless.co/hal_specification.html)
- accountsHalModel = [{
- id: 0,
- user: 'Martin',
- amount: 42,
- transaction: [],
- _links: {
- self: '/accountsHAL/martin'
- }
- }, {
- id: 1,
- user: 'Paul',
- amount: 3.1416,
- transaction: [{
- from: 'Martin',
- amount: 3,
+ id: 1,
+ user: 'Paul',
+ amount: 3.1416,
+ transactions: [{
+ from: 'Martin',
+ amount: 3,
+ id: 0
+ }, {
+ from: 'Anonymous',
+ amount: 0.1416,
+ id: 1
+ }]
+ }],
+
+ nextAccountId: 22,
+
+ // HAL model (http://stateless.co/hal_specification.html)
+ accountsHalModel: [{
id: 0,
+ user: 'Martin',
+ amount: 42,
+ transaction: [],
_links: {
- self: '/accountsHAL/paul/transactions/0'
+ self: '/accountsHAL/martin'
}
}, {
- from: 'Anonymous',
- amount: 0.1416,
id: 1,
+ user: 'Paul',
+ amount: 3.1416,
+ transaction: [{
+ from: 'Martin',
+ amount: 3,
+ id: 0,
+ _links: {
+ self: '/accountsHAL/paul/transactions/0'
+ }
+ }, {
+ from: 'Anonymous',
+ amount: 0.1416,
+ id: 1,
+ _links: {
+ self: '/accountsHAL/paul/transactions/1'
+ }
+ }],
_links: {
- self: '/accountsHAL/paul/transactions/1'
+ self: '/accountsHAL/paul'
}
}],
- _links: {
- self: '/accountsHAL/paul'
- }
- }];
- infoModel = {
- id: 0,
- text: 'Some additional account information'
- };
+ infoModel: {
+ id: 0,
+ text: 'Some additional account information'
+ },
- newAccount = {
- user: 'First User',
- amount: 45,
- transactions: []
- };
+ newAccount: {
+ user: 'First User',
+ amount: 45,
+ transactions: []
+ },
- messages = [{
- id: 23,
- name: 'Gonto'
- }, {
- id: 45,
- name: 'John'
- }];
+ messages: [{
+ id: 23,
+ name: 'Gonto'
+ }, {
+ id: 45,
+ name: 'John'
+ }],
- accountsDoSomethingModel = {
- result: 1
+ accountsDoSomethingModel: {
+ result: 1
+ },
+
+ // Another API for testing
+ customers: [{
+ id: 0,
+ name: 'Alice',
+ status: 'active',
+ credit: 4000.0
+ }, {
+ id: 1,
+ name: 'Bob',
+ status: 'active',
+ credit: 4000.0
+ }, {
+ id: 2,
+ name: 'Carl',
+ status: 'active',
+ credit: 4000.0
+ }],
+ publications: [{
+ id: 1,
+ title: 'Sample',
+ content: 'Rich data',
+ tags: [
+ 'science',
+ 'chemistry'
+ ]
+ }],
+ newCustomer: {
+ id: 3,
+ name: 'New',
+ status: 'active',
+ credit: 4000.0
+ }
};
- $httpBackend = $injector.get('$httpBackend');
+ // Set up backend responses
$httpBackend.when('HEAD', '/accounts').respond();
$httpBackend.when('TRACE', '/accounts').respond();
$httpBackend.when('OPTIONS', '/accounts').respond();
- $httpBackend.whenGET('/accounts').respond(accountsModel);
- $httpBackend.whenGET('/accounts/do-something').respond(accountsDoSomethingModel);
- $httpBackend.whenJSONP('/accounts').respond(accountsModel);
- $httpBackend.whenGET('/accounts/0,1').respond(accountsModel);
- $httpBackend.whenGET('/accounts/messages').respond(messages);
- $httpBackend.whenGET('/accounts/1/message').respond(messages[0]);
- $httpBackend.whenGET('/accounts/1/messages').respond(messages);
- $httpBackend.whenGET('/accounts/0').respond(accountsModel[0]);
- $httpBackend.whenGET('/accounts/1').respond(accountsModel[1]);
- $httpBackend.whenJSONP('/accounts/1').respond(accountsModel[1]);
- $httpBackend.whenGET('/accounts/1/transactions').respond(accountsModel[1].transactions);
- $httpBackend.whenGET('/accounts/1/transactions/1').respond(accountsModel[1].transactions[1]);
- $httpBackend.whenGET('/accounts/search/byOwner').respond(accountsModel);
-
- $httpBackend.whenGET('/info').respond(infoModel);
- $httpBackend.whenGET('/accounts/1/info').respond(infoModel);
- $httpBackend.whenPUT('/info').respond(function(method, url, data) {
- return [200, data, ''];
- });
-
- $httpBackend.whenGET('/accountsHAL').respond(accountsHalModel);
- $httpBackend.whenPUT('/accountsHAL/martin').respond(function(method, url, data) {
- accountsHalModel[0] = angular.fromJson(data);
- return [200, data, ''];
- });
-
- // Full URL
- $httpBackend.whenGET('http://accounts.com/all').respond(accountsModel);
-
- $httpBackend.whenPOST('/accounts').respond(function(method, url, data, headers) {
+ // CRUD /accounts
+ $httpBackend.whenGET('/accounts').respond(testData.accountsModel);
+ $httpBackend.whenJSONP('/accounts').respond(testData.accountsModel);
+ $httpBackend.whenPOST('/accounts').respond(function (method, url, data, headers) {
var newData = angular.fromJson(data);
newData.fromServer = true;
- newData.id = nextAccountId;
+ newData.id = testData.nextAccountId;
return [201, JSON.stringify(newData), ''];
});
-
- $httpBackend.whenPOST('/accounts/1/transactions').respond(function(method, url, data, headers) {
+ $httpBackend.whenGET('/accounts/do-something').respond(testData.accountsDoSomethingModel);
+ $httpBackend.whenGET('/accounts/search/byOwner').respond(testData.accountsModel);
+
+ // CRUD /accounts/{id}
+ $httpBackend.whenGET('/accounts/0,1').respond(testData.accountsModel);
+ $httpBackend.whenGET('/accounts/messages').respond(testData.messages);
+ $httpBackend.whenGET('/accounts/1/message').respond(testData.messages[0]);
+ $httpBackend.whenGET('/accounts/1/messages').respond(testData.messages);
+ $httpBackend.whenGET('/accounts/0').respond(testData.accountsModel[0]);
+ $httpBackend.whenGET('/accounts/1').respond(testData.accountsModel[1]);
+ $httpBackend.whenJSONP('/accounts/1').respond(testData.accountsModel[1]);
+ $httpBackend.whenGET('/accounts/1/transactions').respond(testData.accountsModel[1].transactions);
+ $httpBackend.whenGET('/accounts/1/transactions/1').respond(testData.accountsModel[1].transactions[1]);
+ $httpBackend.whenPOST('/accounts/1/transactions').respond(function (method, url, data, headers) {
return [201, '', ''];
});
-
- $httpBackend.whenDELETE('/accounts/1/transactions/1').respond(function(method, url, data, headers) {
+ $httpBackend.whenDELETE('/accounts/1/transactions/1').respond(function (method, url, data, headers) {
return [200, '', ''];
});
-
- $httpBackend.whenDELETE('/accounts/1').respond(function(method, url, data, headers) {
+ $httpBackend.whenDELETE('/accounts/1').respond(function (method, url, data, headers) {
return [200, '', ''];
});
-
- $httpBackend.whenPOST('/accounts/1').respond(function(method, url, data, headers) {
+ $httpBackend.whenPOST('/accounts/1').respond(function (method, url, data, headers) {
return [200, '', ''];
});
-
- $httpBackend.whenPUT('/accounts/1').respond(function(method, url, data, headers) {
- accountsModel[1] = angular.fromJson(data);
+ $httpBackend.whenPUT('/accounts/1').respond(function (method, url, data, headers) {
+ testData.accountsModel[1] = angular.fromJson(data);
return [201, data, ''];
});
- $httpBackend.whenGET('/error').respond(function() {
- return [500, {}, ''];
+
+ $httpBackend.whenGET('/info').respond(testData.infoModel);
+ $httpBackend.whenGET('/accounts/1/info').respond(testData.infoModel);
+ $httpBackend.whenPUT('/info').respond(function (method, url, data) {
+ return [200, data, ''];
});
- $httpBackend.whenGET('/misc/zero').respond(function() {
- return [200, 0, ''];
+ $httpBackend.whenGET('/accountsHAL').respond(testData.accountsHalModel);
+ $httpBackend.whenPUT('/accountsHAL/martin').respond(function (method, url, data) {
+ testData.accountsHalModel[0] = angular.fromJson(data);
+ return [200, data, ''];
});
- $httpBackend.whenPOST('/customs').respond(function(method, url, data, headers) {
- if (JSON.parse(data).one) {
- return [201, '', ''];
- } else {
- return [400, '', ''];
- }
+ // Full URL
+ $httpBackend.whenGET('http://accounts.com/all').respond(testData.accountsModel);
+
+ $httpBackend.whenGET('/error').respond(function () {
+ return [500, {}, ''];
+ });
+
+ $httpBackend.whenGET('/misc/zero').respond(function () {
+ return [200, 0, ''];
});
// return the status code given
// e.g.: /error/404 returns 404 Not Found
var urlRegex = /\/error\/(\d{3})/;
- $httpBackend.whenGET(urlRegex).respond(function(method, url, data, headers) {
+ $httpBackend.whenGET(urlRegex).respond(function (method, url, data, headers) {
return [url.match(urlRegex)[1], {}, ''];
});
- Restangular = $injector.get('Restangular');
- restangularAccounts = Restangular.all('accounts');
- restangularAccount0 = Restangular.one('accounts', 0);
- restangularAccount1 = Restangular.one('accounts', 1);
-
-
- // Another API for testing
- customers = [{
- id: 0,
- name: 'Alice',
- status: 'active',
- credit: 4000.0
- }, {
- id: 1,
- name: 'Bob',
- status: 'active',
- credit: 4000.0
- }, {
- id: 2,
- name: 'Carl',
- status: 'active',
- credit: 4000.0
- }];
- publications = [{
- id: 1,
- title: 'Sample',
- content: 'Rich data',
- tags: [
- 'science',
- 'chemistry'
- ]
- }];
- newCustomer = {
- id: 3,
- name: 'New',
- status: 'active',
- credit: 4000.0
- };
-
- $httpBackend.whenGET('/customers/').respond(customers);
- $httpBackend.whenGET('http://localhost:8080/customers/').respond(customers);
- $httpBackend.whenGET('api.new.domain/customers/').respond(customers);
- $httpBackend.whenGET('/customers/?active=true').respond(customers);
- $httpBackend.whenGET('/customers/publications/?tags=chemistry').respond(publications);
- $httpBackend.whenPUT('/customers/0').respond(function(method, url, data) {
- customers[0] = angular.fromJson(data);
+ $httpBackend.whenGET('/customers/').respond(testData.customers);
+ $httpBackend.whenGET('http://localhost:8080/customers/').respond(testData.customers);
+ $httpBackend.whenGET('api.new.domain/customers/').respond(testData.customers);
+ $httpBackend.whenGET('/customers/?active=true').respond(testData.customers);
+ $httpBackend.whenGET('/customers/publications/?tags=chemistry').respond(testData.publications);
+ $httpBackend.whenPUT('/customers/0').respond(function (method, url, data) {
+ testData.customers[0] = angular.fromJson(data);
return [200, data, ''];
});
- $httpBackend.whenPOST('/customers/').respond(function(method, url, data, headers) {
+ $httpBackend.whenPOST('/customers/').respond(function (method, url, data, headers) {
var newData = angular.fromJson(data);
newData.fromServer = true;
return [201, JSON.stringify(newData), ''];
});
- }));
+ }); // END OF BEFOREEACH
- afterEach(function() {
+ afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
- describe('Interceptors', function() {
- it('Should add multiple request and response interceptors', function() {
- Restangular.addRequestInterceptor(function(elem) {
+ describe('stripRestangular', function () {
+ // We test stripRestangular by saving objects and checking
+ // the data received by the backend in the POST request.
+ // StripRestangular is used to remove Restangular's methods
+ // from the restangularized POST data (element), but not from raw data.
+
+ it('should not strip Restangular properties from raw POST data', function () {
+ // https://github.com/mgonto/restangular/issues/374
+ var restangularFields = Restangular.configuration.restangularFields;
+ // create an object whose keys are the values of the restangularFields
+ var postData = {};
+ _.each(restangularFields, function (value, key) {
+ postData.value = value;
+ });
+ // we don't want our post data to be treated as a restangularized object
+ postData.restangularized = false;
+ // when posting, restangular shouldn't remove any of our properties
+ var expectedData = angular.copy(postData);
+
+ $httpBackend.expectPOST('/accounts/1/merge', expectedData).respond(200);
+ var parent = Restangular.restangularizeElement(null, {id: 1}, 'accounts', true);
+ parent.post('merge', postData);
+ $httpBackend.flush();
+ });
+
+ it('should not strip "original" Restangular properties in restangularized POST data when overriding restangularFields', function () {
+ // https://github.com/mgonto/restangular/issues/374
+ // Here, we want to post a data object with fields
+ // that normally are used by Restangular, such that save, ids, options etc.
+ // We do that by taking each field in restangularFields and overriding it
+ // with something else, making restangular use different properties
+ // for its internal properties and functions, freeing the original ones
+ // for use in our data object
+
+ // these are the original field names used by restangular
+ var restangularFields = Restangular.configuration.restangularFields;
+ // create an object whose keys are the values of the restangularFields
+ // i.e. {save: "save", clone: "clone", doPOST: "doPOST", ...}
+ var postData = {};
+ _.each(restangularFields, function (value, key) {
+ postData.value = value;
+ });
+ // we expect the http service to get all of these "original" properties in the data object
+ var expectedData = angular.copy(postData);
+
+ // Override the field names used internally by Restangular,
+ // the new config will be something like
+ // {id: '_id', save: '_save', clone: '_clone', ...}
+ var newFieldConfig = {};
+ _.each(restangularFields, function (value, key) {
+ newFieldConfig[key] = '_' + key;
+ });
+ Restangular.setRestangularFields(newFieldConfig);
+
+ // Restangularize the data as an element to save
+ var parent = Restangular.restangularizeElement(null, postData, 'accounts', false);
+
+ // make the POST and check the posted data
+ $httpBackend.expectPOST('/accounts', expectedData).respond(200);
+ parent._save(); // we've overriden the save method as _save
+ $httpBackend.flush();
+ });
+ });
+
+ describe('Interceptors', function () {
+ it('Should add multiple request and response interceptors', function () {
+ Restangular.addRequestInterceptor(function (elem) {
var elemCopy = angular.copy(elem);
elemCopy.firstRequestInterceptor = true;
return elemCopy;
});
- Restangular.addRequestInterceptor(function(elem) {
+ Restangular.addRequestInterceptor(function (elem) {
expect(elem.firstRequestInterceptor).toBeDefined();
var elemCopy = angular.copy(elem);
elemCopy.secondRequestInterceptor = true;
return elemCopy;
});
- Restangular.addFullRequestInterceptor(function(elem) {
+ Restangular.addFullRequestInterceptor(function (elem) {
expect(elem.firstRequestInterceptor).toBeDefined();
expect(elem.secondRequestInterceptor).toBeDefined();
var elemCopy = angular.copy(elem);
@@ -261,20 +321,20 @@ describe('Restangular', function() {
};
});
- Restangular.addResponseInterceptor(function(elem) {
+ Restangular.addResponseInterceptor(function (elem) {
var elemCopy = angular.copy(elem);
elemCopy.firstResponseInterceptor = true;
return elemCopy;
});
- Restangular.addResponseInterceptor(function(elem) {
+ Restangular.addResponseInterceptor(function (elem) {
expect(elem.firstResponseInterceptor).toBeDefined();
var elemCopy = angular.copy(elem);
elemCopy.secondResponseInterceptor = true;
return elemCopy;
});
- $httpBackend.whenPOST('/list').respond(function(method, url, data, headers) {
+ $httpBackend.whenPOST('/list').respond(function (method, url, data, headers) {
var elem = angular.fromJson(data);
expect(elem.firstRequestInterceptor).toBeDefined();
expect(elem.secondRequestInterceptor).toBeDefined();
@@ -286,7 +346,7 @@ describe('Restangular', function() {
Restangular.all('list').post({
name: 'Gonto'
- }).then(function(elem) {
+ }).then(function (elem) {
expect(elem.firstResponseInterceptor).toBeDefined();
expect(elem.secondResponseInterceptor).toBeDefined();
});
@@ -294,24 +354,24 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should add multiple error interceptors', function() {
+ it('Should add multiple error interceptors', function () {
$httpBackend.expectGET('/error');
- var CallbackManager = function() {};
- CallbackManager.successCallback = function() {
+ var CallbackManager = function () {};
+ CallbackManager.successCallback = function () {
expect(CallbackManager.successCallback).not.toHaveBeenCalled();
};
- CallbackManager.errorCallback = function() {
+ CallbackManager.errorCallback = function () {
expect(CallbackManager.firstErrorInterceptor).toHaveBeenCalled();
expect(CallbackManager.secondErrorInterceptor).toHaveBeenCalled();
};
- CallbackManager.firstErrorInterceptor = function() {};
- CallbackManager.secondErrorInterceptor = function() {};
+ CallbackManager.firstErrorInterceptor = function () {};
+ CallbackManager.secondErrorInterceptor = function () {};
- spyOn(CallbackManager, 'successCallback').andCallThrough();
- spyOn(CallbackManager, 'firstErrorInterceptor').andCallThrough();
- spyOn(CallbackManager, 'secondErrorInterceptor').andCallThrough();
+ spyOn(CallbackManager, 'successCallback').and.callThrough();
+ spyOn(CallbackManager, 'firstErrorInterceptor').and.callThrough();
+ spyOn(CallbackManager, 'secondErrorInterceptor').and.callThrough();
Restangular.addErrorInterceptor(CallbackManager.firstErrorInterceptor);
Restangular.addErrorInterceptor(CallbackManager.secondErrorInterceptor);
@@ -323,26 +383,26 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should add multiple error interceptors but don\'t reject the promise if one of them returns false', function() {
+ it('Should add multiple error interceptors but don\'t reject the promise if one of them returns false', function () {
$httpBackend.expectGET('/error');
- var CallbackManager = function() {};
- CallbackManager.successCallback = function() {
+ var CallbackManager = function () {};
+ CallbackManager.successCallback = function () {
expect(CallbackManager.successCallback).not.toHaveBeenCalled();
};
- CallbackManager.errorCallback = function() {
+ CallbackManager.errorCallback = function () {
expect(CallbackManager.errorCallback).not.toHaveBeenCalled();
};
- CallbackManager.firstErrorInterceptor = function() {
+ CallbackManager.firstErrorInterceptor = function () {
return true;
};
- CallbackManager.secondErrorInterceptor = function() {
+ CallbackManager.secondErrorInterceptor = function () {
return false; // prevent promise to be rejected
};
- spyOn(CallbackManager, 'successCallback').andCallThrough();
- spyOn(CallbackManager, 'errorCallback').andCallThrough();
+ spyOn(CallbackManager, 'successCallback').and.callThrough();
+ spyOn(CallbackManager, 'errorCallback').and.callThrough();
Restangular.addErrorInterceptor(CallbackManager.firstErrorInterceptor);
Restangular.addErrorInterceptor(CallbackManager.secondErrorInterceptor);
@@ -354,26 +414,26 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should add multiple error interceptors for a single get too', function() {
+ it('Should add multiple error interceptors for a single get too', function () {
$httpBackend.expectGET('/error/404');
- var CallbackManager = function() {};
- CallbackManager.successCallback = function() {
+ var CallbackManager = function () {};
+ CallbackManager.successCallback = function () {
expect(CallbackManager.successCallback).not.toHaveBeenCalled();
};
- CallbackManager.errorCallback = function() {
+ CallbackManager.errorCallback = function () {
expect(CallbackManager.firstErrorInterceptor).toHaveBeenCalled();
expect(CallbackManager.secondErrorInterceptor).toHaveBeenCalled();
};
- CallbackManager.firstErrorInterceptor = function(response) {
+ CallbackManager.firstErrorInterceptor = function (response) {
expect(Number(response.status)).toEqual(404);
};
- CallbackManager.secondErrorInterceptor = function() {};
+ CallbackManager.secondErrorInterceptor = function () {};
- spyOn(CallbackManager, 'successCallback').andCallThrough();
- spyOn(CallbackManager, 'firstErrorInterceptor').andCallThrough();
- spyOn(CallbackManager, 'secondErrorInterceptor').andCallThrough();
+ spyOn(CallbackManager, 'successCallback').and.callThrough();
+ spyOn(CallbackManager, 'firstErrorInterceptor').and.callThrough();
+ spyOn(CallbackManager, 'secondErrorInterceptor').and.callThrough();
Restangular.addErrorInterceptor(CallbackManager.firstErrorInterceptor);
Restangular.addErrorInterceptor(CallbackManager.secondErrorInterceptor);
@@ -386,17 +446,17 @@ describe('Restangular', function() {
});
});
- describe('Transformers', function() {
- it('Should decorate element both on server and local by default', function() {
+ describe('Transformers', function () {
+ it('Should decorate element both on server and local by default', function () {
- Restangular.extendModel('accounts', function(account) {
- account.extended = function() {
+ Restangular.extendModel('accounts', function (account) {
+ account.extended = function () {
return true;
};
return account;
});
- Restangular.one('accounts', 1).get().then(function(account) {
+ Restangular.one('accounts', 1).get().then(function (account) {
expect(account.extended).toBeDefined();
});
@@ -409,9 +469,9 @@ describe('Restangular', function() {
});
- describe('With Suffix', function() {
- it('shouldn\'t add suffix to getRestangularUrl', function() {
- var suffixRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ describe('With Suffix', function () {
+ it('shouldn\'t add suffix to getRestangularUrl', function () {
+ var suffixRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRequestSuffix('.json');
});
var collection = suffixRestangular.all('accounts');
@@ -419,8 +479,8 @@ describe('Restangular', function() {
expect(collection.one('1').getRestangularUrl()).toBe('/accounts/1');
});
- it('should add suffix to getRequestedUrl', function() {
- var suffixRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ it('should add suffix to getRequestedUrl', function () {
+ var suffixRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRequestSuffix('.json');
});
var collection = suffixRestangular.all('accounts');
@@ -428,8 +488,8 @@ describe('Restangular', function() {
expect(collection.one('1').getRequestedUrl()).toBe('/accounts/1.json');
});
- it('should add suffix to request', function() {
- var suffixRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ it('should add suffix to request', function () {
+ var suffixRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRequestSuffix('.json');
});
var collection = suffixRestangular.all('accounts');
@@ -440,8 +500,8 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('shouldn\'t add suffix to allUrl', function() {
- var suffixRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ it('shouldn\'t add suffix to allUrl', function () {
+ var suffixRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRequestSuffix('.json');
});
$httpBackend.expectGET('http://accounts.com/all');
@@ -450,8 +510,8 @@ describe('Restangular', function() {
});
});
- describe('JSONp', function() {
- it('should work for get', function() {
+ describe('JSONp', function () {
+ it('should work for get', function () {
Restangular.setJsonp(true);
Restangular.one('accounts', 1).get();
@@ -459,7 +519,7 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should work for getList', function() {
+ it('should work for getList', function () {
Restangular.setJsonp(true);
Restangular.all('accounts').getList();
@@ -467,7 +527,7 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('shouldn\'t override post', function() {
+ it('shouldn\'t override post', function () {
Restangular.setJsonp(true);
restangularAccounts.post({
id: 2,
@@ -481,9 +541,9 @@ describe('Restangular', function() {
});
- describe('Local data', function() {
- it('Should restangularize a collection OK', function() {
- var collection = angular.copy(accountsModel);
+ describe('Local data', function () {
+ it('Should restangularize a collection OK', function () {
+ var collection = angular.copy(testData.accountsModel);
Restangular.restangularizeCollection(null, collection, 'accounts');
@@ -495,8 +555,8 @@ describe('Restangular', function() {
});
- it('Should restangularize a function with arguments OK', function() {
- var collection = function(a, b) {};
+ it('Should restangularize a function with arguments OK', function () {
+ var collection = function (a, b) {};
Restangular.restangularizeCollection(null, collection, 'accounts');
@@ -505,7 +565,7 @@ describe('Restangular', function() {
expect(collection.getRestangularUrl()).toBe('/accounts');
});
- it('should have fromServer set when restangularizeElement is called with that param', function() {
+ it('should have fromServer set when restangularizeElement is called with that param', function () {
var element = Restangular.restangularizeElement(null, {}, 'accounts', true);
expect(element.fromServer).toEqual(true);
@@ -516,7 +576,7 @@ describe('Restangular', function() {
expect(element.fromServer).toEqual(false);
});
- it('should have fromServer set when restangularizeCollection is called with that param', function() {
+ it('should have fromServer set when restangularizeCollection is called with that param', function () {
var collection = Restangular.restangularizeCollection(null, [{}], 'accounts', true);
expect(collection[0].fromServer).toEqual(true);
@@ -528,11 +588,11 @@ describe('Restangular', function() {
});
});
- describe('restangularizePromiseIntercept', function() {
- it('should be invoked by restangularizePromise', function() {
+ describe('restangularizePromiseIntercept', function () {
+ it('should be invoked by restangularizePromise', function () {
var calledWithPromise;
- Restangular.setRestangularizePromiseInterceptor(function(promise) {
+ Restangular.setRestangularizePromiseInterceptor(function (promise) {
calledWithPromise = promise;
promise.$object.$custom = true;
@@ -547,8 +607,8 @@ describe('Restangular', function() {
});
});
- describe('$object', function() {
- it('Should work for single get', function() {
+ describe('$object', function () {
+ it('Should work for single get', function () {
var promise = Restangular.one('accounts', 1).get();
var obj = promise.$object;
expect(obj).toBeDefined();
@@ -559,9 +619,9 @@ describe('Restangular', function() {
expect(obj.amount).toEqual(3.1416);
});
- it('Shouldn\'t be restangularized by default', function() {
- Restangular.extendModel('accounts', function(account) {
- account.extended = function() {
+ it('Shouldn\'t be restangularized by default', function () {
+ Restangular.extendModel('accounts', function (account) {
+ account.extended = function () {
return true;
};
return account;
@@ -575,7 +635,7 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should work for single get', function() {
+ it('Should work for single get', function () {
var promise = Restangular.all('accounts').getList();
var list = promise.$object;
expect(list).toBeDefined();
@@ -588,120 +648,120 @@ describe('Restangular', function() {
});
});
- describe('ALL', function() {
- it('getList() should return an array of items', function() {
- restangularAccounts.getList().then(function(accounts) {
- expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(accountsModel));
+ describe('ALL', function () {
+ it('getList() should return an array of items', function () {
+ restangularAccounts.getList().then(function (accounts) {
+ expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(testData.accountsModel));
});
$httpBackend.flush();
});
- it('several getList() should return an array of items', function() {
+ it('several getList() should return an array of items', function () {
$httpBackend.expectGET('/accounts/0,1');
- Restangular.several('accounts', 0, 1).getList().then(function(accounts) {
- expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(accountsModel));
+ Restangular.several('accounts', 0, 1).getList().then(function (accounts) {
+ expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(testData.accountsModel));
});
$httpBackend.flush();
});
- it('several remove() should work', function() {
+ it('several remove() should work', function () {
$httpBackend.expectDELETE('/accounts/0,1').respond([200, '', '']);
Restangular.several('accounts', 0, 1).remove();
$httpBackend.flush();
});
- it('get(id) should return the item with given id', function() {
- restangularAccounts.get(0).then(function(account) {
- expect(Restangular.stripRestangular(account)).toEqual(Restangular.stripRestangular(accountsModel[0]));
+ it('get(id) should return the item with given id', function () {
+ restangularAccounts.get(0).then(function (account) {
+ expect(Restangular.stripRestangular(account)).toEqual(Restangular.stripRestangular(testData.accountsModel[0]));
});
$httpBackend.flush();
});
- it('uses all to get the list without parameters', function() {
+ it('uses all to get the list without parameters', function () {
Restangular.one('accounts', 1).all('messages').getList();
$httpBackend.expectGET('/accounts/1/messages');
$httpBackend.flush();
});
- it('Custom GET methods should work', function() {
- restangularAccounts.customGETLIST('messages').then(function(msgs) {
- expect(Restangular.stripRestangular(msgs)).toEqual(Restangular.stripRestangular(messages));
+ it('Custom GET methods should work', function () {
+ restangularAccounts.customGETLIST('messages').then(function (msgs) {
+ expect(Restangular.stripRestangular(msgs)).toEqual(Restangular.stripRestangular(testData.messages));
});
$httpBackend.flush();
});
- it('post() should add a new item', function() {
+ it('post() should add a new item', function () {
restangularAccounts.post({
id: 2,
user: 'Someone'
- }).then(function() {
- expect(accountsModel.length).toEqual(2);
+ }).then(function () {
+ expect(testData.accountsModel.length).toEqual(2);
});
$httpBackend.expectPOST('/accounts').respond(201, '');
$httpBackend.flush();
});
- it('customPOST() should add a new item', function() {
+ it('customPOST() should add a new item', function () {
restangularAccounts.customPOST({
id: 2,
user: 'Someone'
- }).then(function() {
- expect(accountsModel.length).toEqual(2);
+ }).then(function () {
+ expect(testData.accountsModel.length).toEqual(2);
});
$httpBackend.expectPOST('/accounts').respond(201, '');
$httpBackend.flush();
});
- it('post() should work with arrays', function() {
+ it('post() should work with arrays', function () {
Restangular.all('places').post([{
name: 'Gonto'
}, {
name: 'John'
- }]).then(function(value) {
+ }]).then(function (value) {
expect(value.length).toEqual(2);
});
- $httpBackend.expectPOST('/places').respond(function(method, url, data, headers) {
+ $httpBackend.expectPOST('/places').respond(function (method, url, data, headers) {
return [201, angular.fromJson(data), ''];
});
$httpBackend.flush();
});
- it('post() should add a new item with data and return the data from the server', function() {
- restangularAccounts.post(newAccount).then(function(added) {
+ it('post() should add a new item with data and return the data from the server', function () {
+ restangularAccounts.post(testData.newAccount).then(function (added) {
expect(added.fromServer).toEqual(true);
- expect(added.id).toEqual(nextAccountId);
- expect(added.user).toEqual(newAccount.user);
+ expect(added.id).toEqual(testData.nextAccountId);
+ expect(added.user).toEqual(testData.newAccount.user);
});
$httpBackend.expectPOST('/accounts');
$httpBackend.flush();
});
- it('Doing a post and then other operation (delete) should call right URLs', function() {
- restangularAccounts.post(newAccount).then(function(added) {
+ it('Doing a post and then other operation (delete) should call right URLs', function () {
+ restangularAccounts.post(testData.newAccount).then(function (added) {
added.remove();
- $httpBackend.expectDELETE('/accounts/' + nextAccountId).respond(201, '');
+ $httpBackend.expectDELETE('/accounts/' + testData.nextAccountId).respond(201, '');
});
$httpBackend.flush();
});
- it('Doing a post to a server that returns no element will return undefined', function() {
- restangularAccounts.getList().then(function(accounts) {
+ it('Doing a post to a server that returns no element will return undefined', function () {
+ restangularAccounts.getList().then(function (accounts) {
var newTransaction = {
id: 1,
name: 'Gonto'
};
- accounts[1].post('transactions', newTransaction).then(function(transaction) {
+ accounts[1].post('transactions', newTransaction).then(function (transaction) {
expect(transaction).toBeUndefined();
});
});
@@ -709,23 +769,23 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('head() should safely return', function() {
- restangularAccounts.head().then(function() {
+ it('head() should safely return', function () {
+ restangularAccounts.head().then(function () {
expect(true).toBe(true);
});
$httpBackend.flush();
});
- it('trace() should safely return', function() {
- restangularAccounts.trace().then(function() {
+ it('trace() should safely return', function () {
+ restangularAccounts.trace().then(function () {
expect(true).toBe(true);
});
$httpBackend.flush();
});
- it('customPUT should work', function() {
- $httpBackend.expectPUT('/accounts/hey').respond(accountsModel);
+ it('customPUT should work', function () {
+ $httpBackend.expectPUT('/accounts/hey').respond(testData.accountsModel);
restangularAccounts.customPUT({
key: 'value'
}, 'hey');
@@ -733,50 +793,50 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('customPATCH should work', function() {
+ it('customPATCH should work', function () {
var data = {
foo: 'bar'
};
- $httpBackend.expectPATCH('/accounts/hey', data).respond(accountsModel);
+ $httpBackend.expectPATCH('/accounts/hey', data).respond(testData.accountsModel);
restangularAccounts.customPATCH(data, 'hey');
$httpBackend.flush();
});
- it('options() should safely return', function() {
- restangularAccounts.options().then(function() {
+ it('options() should safely return', function () {
+ restangularAccounts.options().then(function () {
expect(true).toBe(true);
});
$httpBackend.flush();
});
- it('getList() should correctly handle params after customDELETE', function() {
- $httpBackend.expectGET('/accounts?foo=1').respond(accountsModel);
+ it('getList() should correctly handle params after customDELETE', function () {
+ $httpBackend.expectGET('/accounts?foo=1').respond(testData.accountsModel);
restangularAccounts.getList({
foo: 1
- }).then(function() {
+ }).then(function () {
$httpBackend.expectDELETE('/accounts?id=1').respond(201, '');
return restangularAccounts.customDELETE('', {
id: 1
});
- }).then(function() {
- $httpBackend.expectGET('/accounts?foo=1').respond(accountsModel);
+ }).then(function () {
+ $httpBackend.expectGET('/accounts?foo=1').respond(testData.accountsModel);
return restangularAccounts.getList({
foo: 1
});
- }).then(function(accounts) {
- expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(accountsModel));
+ }).then(function (accounts) {
+ expect(Restangular.stripRestangular(accounts)).toEqual(Restangular.stripRestangular(testData.accountsModel));
});
$httpBackend.flush();
});
});
- describe('Scoped Service', function() {
+ describe('Scoped Service', function () {
- it('should correctly work', function() {
+ it('should correctly work', function () {
var Accounts = Restangular.service('accounts');
- Accounts.post(newAccount);
+ Accounts.post(testData.newAccount);
Accounts.one(0).get();
Accounts.getList();
@@ -786,9 +846,9 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should correctly work with children', function() {
+ it('should correctly work with children', function () {
var Transactions = Restangular.service('transactions', restangularAccount1);
- Transactions.post(newAccount);
+ Transactions.post(testData.newAccount);
Transactions.one(1).get();
Transactions.getList();
Transactions.get(1);
@@ -800,9 +860,9 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should add custom collection method added with withConfig', function() {
- var Accounts = Restangular.withConfig(function(RestangularConfigurer) {
- RestangularConfigurer.addElementTransformer('accounts', true, function(worker) {
+ it('should add custom collection method added with withConfig', function () {
+ var Accounts = Restangular.withConfig(function (RestangularConfigurer) {
+ RestangularConfigurer.addElementTransformer('accounts', true, function (worker) {
worker.addRestangularMethod('doSomething', 'get', 'do-something');
return worker;
});
@@ -811,7 +871,7 @@ describe('Restangular', function() {
expect(Accounts.doSomething).toBeDefined();
expect(_.isFunction(Accounts.doSomething)).toBeTruthy();
- Accounts.post(newAccount);
+ Accounts.post(testData.newAccount);
Accounts.one(0).get();
Accounts.getList();
Accounts.doSomething();
@@ -825,30 +885,30 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should provide a one-off $http configuration method', function() {
+ it('should provide a one-off $http configuration method', function () {
var Accounts = Restangular.service('accounts');
Accounts.withHttpConfig({
transformRequest: angular.identity
});
- Accounts.post(newAccount);
+ Accounts.post(testData.newAccount);
$httpBackend.expectPOST('/accounts');
$httpBackend.flush();
});
});
- describe('ONE', function() {
- it('get() should return a JSON item', function() {
- restangularAccount1.get().then(function(account) {
+ describe('ONE', function () {
+ it('get() should return a JSON item', function () {
+ restangularAccount1.get().then(function (account) {
expect(Restangular.stripRestangular(account))
- .toEqual(Restangular.stripRestangular(accountsModel[1]));
+ .toEqual(Restangular.stripRestangular(testData.accountsModel[1]));
});
$httpBackend.flush();
});
- it('Should save as put correctly', function() {
- restangularAccount1.get().then(function(account) {
+ it('Should save as put correctly', function () {
+ restangularAccount1.get().then(function (account) {
$httpBackend.expectPUT('/accounts/1');
account.put();
});
@@ -856,7 +916,7 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should save as post correctly', function() {
+ it('Should save as post correctly', function () {
var account1 = angular.copy(restangularAccount1);
$httpBackend.expectPOST('/accounts/1');
account1.name = 'Hey';
@@ -865,52 +925,52 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should keep route property when element is created', function() {
+ it('Should keep route property when element is created', function () {
var account1 = Restangular.restangularizeElement(null, {}, 'accounts');
$httpBackend.expectPOST('/accounts');
$httpBackend.expectPUT('/accounts/1');
account1.name = 'Hey';
- account1.save().then(function(accountFromServer) {
+ account1.save().then(function (accountFromServer) {
accountFromServer.id = 1;
return accountFromServer.save();
- }).then(function(accountFromServer2) {
+ }).then(function (accountFromServer2) {
expect(accountFromServer2.route).toBe(account1.route);
});
$httpBackend.flush();
});
- it('Should make RequestLess connections with one', function() {
- restangularAccount1.one('transactions', 1).get().then(function(transaction) {
+ it('Should make RequestLess connections with one', function () {
+ restangularAccount1.one('transactions', 1).get().then(function (transaction) {
expect(Restangular.stripRestangular(transaction))
- .toEqual(Restangular.stripRestangular(accountsModel[1].transactions[1]));
+ .toEqual(Restangular.stripRestangular(testData.accountsModel[1].transactions[1]));
});
$httpBackend.flush();
});
- it('Should make RequestLess connections with all', function() {
- restangularAccount1.all('transactions').getList().then(function(transactions) {
+ it('Should make RequestLess connections with all', function () {
+ restangularAccount1.all('transactions').getList().then(function (transactions) {
expect(Restangular.stripRestangular(transactions))
- .toEqual(Restangular.stripRestangular(accountsModel[1].transactions));
+ .toEqual(Restangular.stripRestangular(testData.accountsModel[1].transactions));
});
$httpBackend.flush();
});
- it('Custom GET methods should work', function() {
- restangularAccount1.customGET('message').then(function(msg) {
- expect(Restangular.stripRestangular(msg)).toEqual(Restangular.stripRestangular(messages[0]));
+ it('Custom GET methods should work', function () {
+ restangularAccount1.customGET('message').then(function (msg) {
+ expect(Restangular.stripRestangular(msg)).toEqual(Restangular.stripRestangular(testData.messages[0]));
});
$httpBackend.flush();
});
- it('put() should update the value', function() {
- restangularAccount1.get().then(function(account) {
+ it('put() should update the value', function () {
+ restangularAccount1.get().then(function (account) {
account.amount = 1.618;
- account.put().then(function(newAc) {
- expect(accountsModel[1].amount).toEqual(1.618);
+ account.put().then(function (newAc) {
+ expect(testData.accountsModel[1].amount).toEqual(1.618);
newAc.remove();
$httpBackend.expectDELETE('/accounts/1');
});
@@ -922,11 +982,11 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should return an array when accessing a subvalue', function() {
- restangularAccount1.get().then(function(account) {
- account.getList('transactions').then(function(transactions) {
+ it('should return an array when accessing a subvalue', function () {
+ restangularAccount1.get().then(function (account) {
+ account.getList('transactions').then(function (transactions) {
expect(Restangular.stripRestangular(transactions))
- .toEqual(Restangular.stripRestangular(accountsModel[1].transactions));
+ .toEqual(Restangular.stripRestangular(testData.accountsModel[1].transactions));
});
});
@@ -934,16 +994,16 @@ describe('Restangular', function() {
});
});
- describe('COPY', function() {
- it('should copy an object and "this" should reference the copied object', function() {
- var copiedAccount = Restangular.copy(accountsModel[0]);
+ describe('COPY', function () {
+ it('should copy an object and "this" should reference the copied object', function () {
+ var copiedAccount = Restangular.copy(testData.accountsModel[0]);
var that;
copiedAccount.user = 'Copied string';
- expect(copiedAccount).not.toBe(accountsModel[0]);
+ expect(copiedAccount).not.toBe(testData.accountsModel[0]);
// create a spy for one of the methods to capture the value of 'this'
- spyOn(copiedAccount, 'getRestangularUrl').andCallFake(function() {
+ spyOn(copiedAccount, 'getRestangularUrl').and.callFake(function () {
that = this;
});
@@ -951,13 +1011,13 @@ describe('Restangular', function() {
expect(that).toBe(copiedAccount);
});
- it('should copy an object and "fromServer" param should be the same with the copied object', function() {
+ it('should copy an object and "fromServer" param should be the same with the copied object', function () {
var responseHandler = jasmine.createSpy();
// with fromServer=true
restangularAccount1.get().then(responseHandler);
$httpBackend.flush();
- var account = responseHandler.calls[0].args[0],
+ var account = responseHandler.calls.argsFor(0)[0],
copiedAccount = Restangular.copy(account);
expect(account.fromServer).toEqual(true);
expect(copiedAccount.fromServer).toEqual(true);
@@ -981,7 +1041,7 @@ describe('Restangular', function() {
// with collections, fromServer = true;
restangularAccounts.getList().then(responseHandler);
$httpBackend.flush();
- accounts = responseHandler.calls[0].args[0],
+ accounts = responseHandler.calls.argsFor(0)[0],
copiedAccounts = Restangular.copy(accounts);
expect(accounts.fromServer).toEqual(true);
expect(copiedAccounts.fromServer).toEqual(true);
@@ -1014,71 +1074,135 @@ describe('Restangular', function() {
});
});
- describe('getRestangularUrl', function() {
- it('should return the generated URL when you chain Restangular methods together', function() {
+ describe('getRestangularUrl', function () {
+ it('should get the URL for the current object', function () {
+ var element = Restangular.one('accounts', 123);
+ expect(element.getRestangularUrl()).toEqual('/accounts/123');
+ });
+ it('should not include query parameters', function () {
+ var responseHandler = jasmine.createSpy(), element;
+ $httpBackend.expectGET('/accounts/123?query=params').respond({id: 123, name: 'account123'});
+ Restangular.one('accounts', 123).get({query: 'params'}).then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(element.getRestangularUrl()).toEqual('/accounts/123');
+ });
+ it('should be the same for the built resource as for the fetched resource', function () {
+ var responseHandler = jasmine.createSpy(), element, resource;
+ $httpBackend.expectGET('/accounts/123').respond({id: 123, name: 'Account 123'});
+ resource = Restangular.one('accounts', 123);
+ resource.get().then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(resource.getRestangularUrl()).toEqual('/accounts/123');
+ expect(element.getRestangularUrl()).toEqual('/accounts/123');
+ });
+ it('should use the id from the response, not the request', function () {
+ var responseHandler = jasmine.createSpy(), element, resource;
+ $httpBackend.expectGET('/accounts/123').respond({id: 444, name: 'Account 444'});
+ resource = Restangular.one('accounts', 123);
+ resource.get().then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(resource.getRestangularUrl()).toEqual('/accounts/123');
+ expect(element.getRestangularUrl()).toEqual('/accounts/444');
+ });
+ it('should have an empty id in the URL if the response id is empty', function () {
+ // https://github.com/mgonto/restangular/issues/1421
+ var responseHandler = jasmine.createSpy(), element, resource;
+ $httpBackend.expectGET('/accounts/123').respond({name: 'Account 444'});
+ resource = Restangular.one('accounts', 123);
+ resource.get().then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(resource.getRestangularUrl()).toEqual('/accounts/123');
+ expect(element.getRestangularUrl()).toEqual('/accounts');
+ });
+ it('should return the generated URL for PUTed elements', function () {
+ var responseHandler = jasmine.createSpy(), element;
+ $httpBackend.expectPUT('/accounts/123').respond({id: 123, name: 'Account 123'});
+ Restangular.one('accounts', 123).put().then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(element.getRestangularUrl()).toEqual('/accounts/123');
+ });
+ it('should return the generated URL for POSTed elements', function () {
+ var responseHandler = jasmine.createSpy(), element;
+ $httpBackend.expectPOST('/accounts').respond({id: 123, name: 'Account 123'});
+ Restangular.restangularizeElement(null, {name: 'Account 123'}, 'accounts', false, false).save().then(responseHandler);
+ $httpBackend.flush();
+
+ element = responseHandler.calls.argsFor(0)[0];
+ expect(element.getRestangularUrl()).toEqual('/accounts/123');
+ });
+ it('should return the generated URL when you chain Restangular methods together', function () {
var restangularSpaces = Restangular.one('accounts', 123).one('buildings', 456).all('spaces');
expect(restangularSpaces.getRestangularUrl()).toEqual('/accounts/123/buildings/456/spaces');
});
- });
- describe('getRestangularUrl with useCannonicalId set to true', function() {
- it('should return the generated URL when you chain Restangular methods together', function() {
- var R = Restangular.withConfig(function(config) {
- config.setUseCannonicalId(true);
+ describe('with useCannonicalId set to true', function () {
+ it('should return the generated URL when you chain Restangular methods together', function () {
+ var R = Restangular.withConfig(function (config) {
+ config.setUseCannonicalId(true);
+ });
+ var restangularSpaces = R.one('accounts', 123).one('buildings', 456).all('spaces');
+ expect(restangularSpaces.getRestangularUrl()).toEqual('/accounts/123/buildings/456/spaces');
});
- var restangularSpaces = R.one('accounts', 123).one('buildings', 456).all('spaces');
- expect(restangularSpaces.getRestangularUrl()).toEqual('/accounts/123/buildings/456/spaces');
});
});
-
- describe('addElementTransformer', function() {
- it('should allow for a custom method to be placed at the collection level', function() {
+ describe('addElementTransformer', function () {
+ it('should allow for a custom method to be placed at the collection level', function () {
var accountsPromise;
- Restangular.addElementTransformer('accounts', true, function(collection) {
- collection.totalAmount = function() {};
+ Restangular.addElementTransformer('accounts', true, function (collection) {
+ collection.totalAmount = function () {};
return collection;
});
accountsPromise = Restangular.all('accounts').getList();
- accountsPromise.then(function(accounts) {
+ accountsPromise.then(function (accounts) {
expect(typeof accounts.totalAmount).toEqual('function');
});
$httpBackend.flush();
});
- it('should allow for a custom method to be placed at the model level when one model is requested', function() {
+ it('should allow for a custom method to be placed at the model level when one model is requested', function () {
var accountPromise;
- Restangular.addElementTransformer('accounts', false, function(model) {
- model.prettifyAmount = function() {};
+ Restangular.addElementTransformer('accounts', false, function (model) {
+ model.prettifyAmount = function () {};
return model;
});
accountPromise = Restangular.one('accounts', 1).get();
- accountPromise.then(function(account) {
+ accountPromise.then(function (account) {
expect(typeof account.prettifyAmount).toEqual('function');
});
$httpBackend.flush();
});
- it('should allow for a custom method to be placed at the model level when several models are requested', function() {
+ it('should allow for a custom method to be placed at the model level when several models are requested', function () {
var accountsPromise;
- Restangular.addElementTransformer('accounts', false, function(model) {
- model.prettifyAmount = function() {};
+ Restangular.addElementTransformer('accounts', false, function (model) {
+ model.prettifyAmount = function () {};
return model;
});
accountsPromise = Restangular.all('accounts', 1).getList();
- accountsPromise.then(function(accounts) {
- accounts.forEach(function(account) {
+ accountsPromise.then(function (accounts) {
+ accounts.forEach(function (account) {
expect(typeof account.prettifyAmount).toEqual('function');
});
});
@@ -1086,18 +1210,18 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should allow for a custom method to be placed at the collection level using a regexp matching the route', function() {
+ it('should allow for a custom method to be placed at the collection level using a regexp matching the route', function () {
var accountsPromise;
- Restangular.addElementTransformer(/^accounts/, false, function(model) {
- model.prettifyAmount = function() {};
+ Restangular.addElementTransformer(/^accounts/, false, function (model) {
+ model.prettifyAmount = function () {};
return model;
});
accountsPromise = Restangular.all('accounts/search/byOwner', 1).getList();
- accountsPromise.then(function(accounts) {
- accounts.forEach(function(account) {
+ accountsPromise.then(function (accounts) {
+ accounts.forEach(function (account) {
expect(typeof account.prettifyAmount).toEqual('function');
});
});
@@ -1108,7 +1232,7 @@ describe('Restangular', function() {
it('should work with cloned collections', function () {
var responseHandler = jasmine.createSpy();
- Restangular.addElementTransformer(/^accounts/, true, function(collection) {
+ Restangular.addElementTransformer(/^accounts/, true, function (collection) {
collection.customThing = 'customValue';
return collection;
});
@@ -1116,42 +1240,42 @@ describe('Restangular', function() {
Restangular.all('accounts').getList().then(responseHandler);
$httpBackend.flush();
- var accounts = responseHandler.calls[0].args[0];
+ var accounts = responseHandler.calls.argsFor(0)[0];
var accountsCopy = accounts.clone();
expect(accounts.customThing).toEqual('customValue');
expect(accountsCopy.customThing).toEqual('customValue');
});
- it('should allow for a custom method to be placed at the model level using regexp route when one model is requested', function() {
+ it('should allow for a custom method to be placed at the model level using regexp route when one model is requested', function () {
var accountPromise;
- Restangular.addElementTransformer(/^accounts/, false, function(model) {
- model.prettifyAmount = function() {};
+ Restangular.addElementTransformer(/^accounts/, false, function (model) {
+ model.prettifyAmount = function () {};
return model;
});
accountPromise = Restangular.one('accounts', 1).get();
- accountPromise.then(function(account) {
+ accountPromise.then(function (account) {
expect(typeof account.prettifyAmount).toEqual('function');
});
$httpBackend.flush();
});
- it('should allow for a custom method to be placed at the model level using regexp when several models are requested', function() {
+ it('should allow for a custom method to be placed at the model level using regexp when several models are requested', function () {
var accountsPromise;
- Restangular.addElementTransformer(/^accounts/, false, function(model) {
- model.prettifyAmount = function() {};
+ Restangular.addElementTransformer(/^accounts/, false, function (model) {
+ model.prettifyAmount = function () {};
return model;
});
accountsPromise = Restangular.all('accounts', 1).getList();
- accountsPromise.then(function(accounts) {
- accounts.forEach(function(account) {
+ accountsPromise.then(function (accounts) {
+ accounts.forEach(function (account) {
expect(typeof account.prettifyAmount).toEqual('function');
});
});
@@ -1161,12 +1285,12 @@ describe('Restangular', function() {
});
- describe('extendCollection', function() {
- it('should be an alias for a specific invocation of addElementTransformer', function() {
+ describe('extendCollection', function () {
+ it('should be an alias for a specific invocation of addElementTransformer', function () {
var spy = spyOn(Restangular, 'addElementTransformer');
- var fn = function(collection) {
- collection.totalAmount = function() {};
+ var fn = function (collection) {
+ collection.totalAmount = function () {};
return collection;
};
@@ -1176,12 +1300,12 @@ describe('Restangular', function() {
});
});
- describe('extendModel', function() {
- it('should be an alias for a specific invocation of addElementTransformer', function() {
+ describe('extendModel', function () {
+ it('should be an alias for a specific invocation of addElementTransformer', function () {
var spy = spyOn(Restangular, 'addElementTransformer');
- var fn = function(model) {
- model.prettifyAmount = function() {};
+ var fn = function (model) {
+ model.prettifyAmount = function () {};
return model;
};
@@ -1191,8 +1315,8 @@ describe('Restangular', function() {
});
});
- describe('headers', function() {
- it('should return defaultHeaders', function() {
+ describe('headers', function () {
+ it('should return defaultHeaders', function () {
var defaultHeaders = {
testheader: 'header value'
};
@@ -1200,9 +1324,9 @@ describe('Restangular', function() {
expect(Restangular.defaultHeaders).toEqual(defaultHeaders);
});
- it('should pass uppercase methods in X-HTTP-Method-Override', function() {
+ it('should pass uppercase methods in X-HTTP-Method-Override', function () {
Restangular.setMethodOverriders(['put']);
- $httpBackend.expectPOST('/overriders/1').respond(function(method, url, data, headers) {
+ $httpBackend.expectPOST('/overriders/1').respond(function (method, url, data, headers) {
expect(headers['X-HTTP-Method-Override']).toBe('PUT');
return {};
});
@@ -1211,8 +1335,8 @@ describe('Restangular', function() {
});
});
- describe('defaultRequestParams', function() {
- it('should return defaultRequestParams', function() {
+ describe('defaultRequestParams', function () {
+ it('should return defaultRequestParams', function () {
var defaultRequestParams = {
param: 'value'
};
@@ -1222,7 +1346,7 @@ describe('Restangular', function() {
expect(Restangular.requestParams.common).toEqual(defaultRequestParams);
});
- it('should be able to set default params for get, post, put.. methods separately', function() {
+ it('should be able to set default params for get, post, put.. methods separately', function () {
var postParams = {
post: 'value'
},
@@ -1239,7 +1363,7 @@ describe('Restangular', function() {
expect(Restangular.requestParams.common).not.toEqual(putParams);
});
- it('should be able to set default params for multiple methods with array', function() {
+ it('should be able to set default params for multiple methods with array', function () {
var defaultParams = {
param: 'value'
};
@@ -1253,9 +1377,9 @@ describe('Restangular', function() {
});
});
- describe('withConfig', function() {
- it('should create new service with scoped configuration', function() {
- var childRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ describe('withConfig', function () {
+ it('should create new service with scoped configuration', function () {
+ var childRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('/api/v1');
});
@@ -1264,12 +1388,12 @@ describe('Restangular', function() {
});
- it('should allow nested configurations', function() {
- var childRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ it('should allow nested configurations', function () {
+ var childRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('/api/v1');
});
- var grandchildRestangular = childRestangular.withConfig(function(RestangularConfigurer) {
+ var grandchildRestangular = childRestangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRequestSuffix('.json');
});
@@ -1284,9 +1408,9 @@ describe('Restangular', function() {
});
});
- describe('Self linking', function() {
- it('Should request the link in HAL format', function() {
- var linkRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ describe('Self linking', function () {
+ it('Should request the link in HAL format', function () {
+ var linkRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setRestangularFields({
selfLink: '_links.self'
});
@@ -1304,38 +1428,38 @@ describe('Restangular', function() {
});
});
- describe('Singe one (endpoint not expecting an id)', function() {
- it('does not use the id for single resource GET', function() {
+ describe('Singe one (endpoint not expecting an id)', function () {
+ it('does not use the id for single resource GET', function () {
Restangular.one('info', 0, true).get();
$httpBackend.expectGET('/info');
$httpBackend.flush();
});
- it('getRestangularUrl() returns still the url without id after GET', function() {
+ it('getRestangularUrl() returns still the url without id after GET', function () {
var record = Restangular.one('info', 0, true);
- record.get().then(function(data) {
+ record.get().then(function (data) {
expect(data.getRestangularUrl()).toEqual('/info');
});
$httpBackend.expectGET('/info');
$httpBackend.flush();
});
- it('does not use the id for single nested resource GET', function() {
+ it('does not use the id for single nested resource GET', function () {
Restangular.one('accounts', 1).one('info', 0, true).get();
$httpBackend.expectGET('/accounts/1/info');
$httpBackend.flush();
});
- it('does not use the id for single resource PUT', function() {
+ it('does not use the id for single resource PUT', function () {
Restangular.one('info', 0, true).put();
$httpBackend.expectPUT('/info');
$httpBackend.flush();
});
});
- describe('setSelfLinkAbsoluteUrl', function() {
- it('works', function() {
- var childRestangular = Restangular.withConfig(function(RestangularConfigurer) {
+ describe('setSelfLinkAbsoluteUrl', function () {
+ it('works', function () {
+ var childRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setSelfLinkAbsoluteUrl(false);
});
@@ -1344,41 +1468,27 @@ describe('Restangular', function() {
});
});
- describe('Misc', function() {
- it('should not strip [one] or [all] key from plain object', function() {
- Restangular.all('customs').customPOST({
- one: 'I am here',
- two: 'I am also here'
- }).then(function() {
- expect(1).toBe(1);
- }, function() {
- expect('Promise').toBe('correctly fulfilled');
- });
- $httpBackend.flush();
- });
+ describe('Misc', function () {
- it('should not stip non-restangularized elements', function() {
- expect(Restangular.stripRestangular(['test', 'test2'])).toEqual(['test', 'test2']);
- });
-
- it('should accept 0 as response', function() {
- Restangular.one('misc', 'zero').get().then(function(res) {
+ it('should accept 0 as response', function () {
+ Restangular.one('misc', 'zero').get().then(function (res) {
expect(res).toEqual(0);
});
$httpBackend.flush();
});
- it('Should accept 0 as a proper id in custom requests', function() {
+ it('Should accept 0 as a proper id in custom requests', function () {
$httpBackend.expectDELETE('/accounts/0').respond(202);
Restangular.all('accounts').customDELETE(0);
$httpBackend.flush();
});
+
});
- describe('testing normalize url', function() {
+ describe('testing normalize url', function () {
- it('should get a list of objects', function() {
- Restangular.all('customers/').getList().then(function(res) {
+ it('should get a list of objects', function () {
+ Restangular.all('customers/').getList().then(function (res) {
res.getList({
active: true
});
@@ -1390,8 +1500,8 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should get a list of objects even if the path has extra slashes', function() {
- Restangular.all('customers///').getList().then(function(res) {
+ it('should get a list of objects even if the path has extra slashes', function () {
+ Restangular.all('customers///').getList().then(function (res) {
res.getList({
active: true
});
@@ -1401,37 +1511,37 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('should post with slash at the end', function() {
- Restangular.all('customers/').getList().then(function(res) {
- res.post(newCustomer);
+ it('should post with slash at the end', function () {
+ Restangular.all('customers/').getList().then(function (res) {
+ res.post(testData.newCustomer);
$httpBackend.expectPOST('/customers/');
});
$httpBackend.expectGET('/customers/');
$httpBackend.flush();
});
- it('should put with slash at the end', function() {
- Restangular.all('customers/').getList().then(function(customers) {
+ it('should put with slash at the end', function () {
+ Restangular.all('customers/').getList().then(function (customers) {
customers[0].put();
$httpBackend.expectPUT('/customers/0');
});
$httpBackend.flush();
});
- it('should return a normalized URL even it has extra slashes', function() {
+ it('should return a normalized URL even it has extra slashes', function () {
var restangularSpaces = Restangular.one('accounts//', 123).one('buildings//', 456).all('spaces///');
expect(restangularSpaces.getRestangularUrl()).toEqual('/accounts/123/buildings/456/spaces/');
});
- it('should create a new service and still working normalized URL', function() {
- var newRes = Restangular.withConfig(function(RestangularConfigurer) {
+ it('should create a new service and still working normalized URL', function () {
+ var newRes = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('http://localhost:8080');
});
expect(newRes.configuration.baseUrl).toEqual('http://localhost:8080');
newRes.all('customers////').getList();
$httpBackend.expectGET('http://localhost:8080/customers/');
- var newApi = Restangular.withConfig(function(RestangularConfigurer) {
+ var newApi = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('api.new.domain');
});
@@ -1442,8 +1552,8 @@ describe('Restangular', function() {
$httpBackend.flush();
});
- it('Should work with absolute URL with //authority', function() {
- var newRes = Restangular.withConfig(function(RestangularConfigurer) {
+ it('Should work with absolute URL with //authority', function () {
+ var newRes = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('//localhost:8080');
});
expect(newRes.configuration.baseUrl).toEqual('//localhost:8080');
@@ -1454,31 +1564,153 @@ describe('Restangular', function() {
});
});
- describe('setPlainByDefault', function() {
+ describe('setPlainByDefault', function () {
+ var plainByDefaultRestangular;
- it('should not add restangularized methods to response object', function() {
- var newRes = Restangular.withConfig(function(RestangularConfigurer) {
+ beforeEach(function () {
+ plainByDefaultRestangular = Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setPlainByDefault(true);
});
+ });
- expect(newRes.configuration.plainByDefault).toEqual(true);
+ it('should set the property on the configuration', function () {
+ expect(plainByDefaultRestangular.configuration.plainByDefault).toEqual(true);
+ });
- newRes.one('accounts', 0).get().then(function(account) {
- expect(account).toEqual(accountsModel[0]);
+ it('should not add restangularized methods to response object', function () {
+ plainByDefaultRestangular.one('accounts', 0).get().then(function (account) {
+ expect(account).toEqual(testData.accountsModel[0]);
});
+ $httpBackend.flush();
+ });
+ it('shoud not add restangularized methods to response collection', function () {
+ plainByDefaultRestangular.all('accounts').getList().then(function (accounts) {
+ expect(accounts).toEqual(testData.accountsModel);
+ });
$httpBackend.flush();
});
- it('shoud not add restangularized methods to response collection', function() {
- var newRes = Restangular.withConfig(function(RestangularConfigurer) {
- RestangularConfigurer.setPlainByDefault(true);
+ describe('with ETag', function () {
+ beforeEach(function () {
+ $httpBackend.whenGET('/accounts').respond(
+ testData.accountsModel,
+ {'ETag': 'c11ea3f8-3bfd-4be8-a6a6-501dd831b8a4'}
+ );
+ $httpBackend.whenGET('/accounts/1').respond(
+ testData.accountsModel[1],
+ {'ETag': 'bf79b780-f132-4f44-a9eb-7e6eb4f902b2'}
+ );
});
- newRes.all('accounts').getList().then(function(accounts) {
- expect(accounts).toEqual(accountsModel);
+ it('should not add restangularized ETag to response object', function () {
+ plainByDefaultRestangular.one('accounts', 0).get().then(function (account) {
+ expect(account).toEqual(testData.accountsModel[0]);
+ });
+ $httpBackend.flush();
+ });
+
+ it('shoud not add restangularized ETag to response collection', function () {
+ plainByDefaultRestangular.all('accounts').getList().then(function (accounts) {
+ expect(accounts).toEqual(testData.accountsModel);
+ });
+ $httpBackend.flush();
+ });
+ });
+ });
+
+ describe('ETags', function () {
+ beforeEach(function () {
+ $httpBackend.whenGET('/etagAccounts').respond(
+ testData.accountsModel,
+ {'ETag': 'c11ea3f8-3bfd-4be8-a6a6-501dd831b8a4'}
+ );
+ $httpBackend.whenGET('/etagAccounts/1').respond(
+ testData.accountsModel[1],
+ {'ETag': 'bf79b780-f132-4f44-a9eb-7e6eb4f902b2'}
+ );
+ });
+
+ it('should include the ETag in the restangularized element', function () {
+ Restangular.one('etagAccounts', 1).get().then(function (account) {
+ expect(account.restangularEtag).toEqual('bf79b780-f132-4f44-a9eb-7e6eb4f902b2');
});
$httpBackend.flush();
});
+ it('should include the ETag in the restangularized collection', function () {
+ Restangular.all('etagAccounts').getList().then(function (accounts) {
+ expect(accounts.restangularEtag).toEqual('c11ea3f8-3bfd-4be8-a6a6-501dd831b8a4');
+ });
+ $httpBackend.flush();
+ });
+ it('should add the If-Match header on PUT requests', function () {
+ var responseHandler = jasmine.createSpy();
+ Restangular.one('etagAccounts', 1).get().then(responseHandler);
+ $httpBackend.flush();
+
+ var account = responseHandler.calls.argsFor(0)[0];
+ $httpBackend.expect(
+ 'PUT',
+ '/etagAccounts/1',
+ testData.accountsModel[1],
+ function (headers) {
+ return headers['If-Match'] === 'bf79b780-f132-4f44-a9eb-7e6eb4f902b2';
+ }
+ ).respond(200);
+ account.save();
+ $httpBackend.flush();
+ });
+ it('should add the If-Match header on DELETE requests', function () {
+ var responseHandler = jasmine.createSpy();
+ Restangular.one('etagAccounts', 1).get().then(responseHandler);
+ $httpBackend.flush();
+
+ var account = responseHandler.calls.argsFor(0)[0];
+ $httpBackend.expect(
+ 'DELETE',
+ '/etagAccounts/1',
+ testData.accountsModel[1],
+ function (headers) {
+ return headers['If-Match'] === 'bf79b780-f132-4f44-a9eb-7e6eb4f902b2';
+ }
+ ).respond(200);
+ account.remove();
+ $httpBackend.flush();
+ });
+ it('should add the If-None-Match header on GET requests for elements', function () {
+ var responseHandler = jasmine.createSpy();
+ Restangular.one('etagAccounts', 1).get().then(responseHandler);
+ $httpBackend.flush();
+
+ var account = responseHandler.calls.argsFor(0)[0];
+ $httpBackend.expect(
+ 'GET',
+ '/etagAccounts/1',
+ undefined,
+ function (headers) {
+ return headers['If-None-Match'] === 'bf79b780-f132-4f44-a9eb-7e6eb4f902b2';
+ }
+ ).respond(200);
+ account.get();
+ $httpBackend.flush();
+ });
+ it('should add the If-None-Match header on GET requests for collections', function () {
+ var responseHandler = jasmine.createSpy();
+ Restangular.all('etagAccounts').getList().then(responseHandler);
+ $httpBackend.flush();
+
+ var accounts = responseHandler.calls.argsFor(0)[0];
+ $httpBackend.expect(
+ 'GET',
+ '/etagAccounts',
+ undefined,
+ function (headers) {
+ return headers['If-None-Match'] === 'c11ea3f8-3bfd-4be8-a6a6-501dd831b8a4';
+ }
+ ).respond(200);
+ accounts.getList();
+ $httpBackend.flush();
+ });
+
});
});