├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── angular-drupal
├── app
├── .bowerrc
├── app.js
└── index.html
├── bower.json
├── build
└── angular-drupal.min.js
├── karma.conf.js
├── package.json
├── src
└── angular-drupal.js
└── tests
├── DrupalSpec.js
└── support
└── jasmine.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | app/bower_components
3 | npm-debug.log
4 |
5 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | // Project configuration.
4 | grunt.initConfig({
5 | pkg: grunt.file.readJSON('package.json'),
6 | uglify: {
7 | options: {
8 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
9 | },
10 | build: {
11 | src: 'src/*.js',
12 | dest: 'build/<%= pkg.name %>.min.js'
13 | }
14 | },
15 | watch: {
16 | files: ['src/*.js'],
17 | tasks: ['uglify']
18 | }
19 | });
20 |
21 | // Load the plugin that provides the "uglify" task.
22 | grunt.loadNpmTasks('grunt-contrib-uglify');
23 | grunt.loadNpmTasks('grunt-contrib-watch');
24 |
25 | // Default task(s).
26 | grunt.registerTask('default', ['uglify', 'watch']);
27 |
28 | };
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-drupal
2 |
3 | An Angular JS module for Drupal 8 RESTful Web Services.
4 |
5 | ## Intro
6 |
7 | This Angular module makes it easy to `read/write` entity data `to/from` Drupal,
8 | handles user authentication and registration, and makes it easy to retrieve
9 | JSON data from Views.
10 |
11 | Here's a very *simple* Angular app that loads `node # 123` from Drupal and then
12 | displays the node's title (via an `alert`):
13 |
14 | ```
15 | // My simple app.
16 | angular.module('myApp', ['angular-drupal']).run(['drupal', function(drupal) {
17 |
18 | drupal.nodeLoad(123).then(function(node) {
19 | alert(node.label());
20 | });
21 |
22 | }]);
23 |
24 | // The angular-drupal configuration settings for my simple app.
25 | angular.module('angular-drupal').config(function($provide) {
26 |
27 | $provide.value('drupalSettings', {
28 | sitePath: 'http://my-drupal-site.com'
29 | });
30 |
31 | });
32 | ```
33 |
34 | ## Installation and Setup
35 |
36 | There are two main parts to the installation and usage of this module. First,
37 | on your Drupal site you need to install the *jDrupal* module, then
38 | install the *REST UI* module and configure core Drupal REST services, and then include the *angular-drupal*
39 | module and *jDrupal* in your Angular JS application.
40 |
41 | ### 0. jDrupal Module
42 |
43 | https://www.drupal.org/project/jdrupal
44 |
45 | ```
46 | drush dl jdrupal
47 | drush en -y jdrupal
48 | ```
49 |
50 | ### 1. Drupal Setup
51 |
52 | See [jDrupal docs](http://jdrupal.easystreet3.com/8/docs/Install) for details.
53 |
54 | #### 1.1 Enable Drupal core's "RESTful Web Services" module
55 |
56 | #### 1.2 Install the REST UI module
57 |
58 | https://www.drupal.org/project/restui
59 |
60 | Then go to `admin/config/services/rest` and enable your desired resources. We
61 | recommend the following resources, http methods, authentications, and formats:
62 |
63 | ```
64 | User - GET - json - cookie
65 | User - POST - json - cookie
66 | ```
67 |
68 | #### 1.3 Specify User Permissions
69 |
70 | Go to admin/people/permissions and allow a user role(s) to access some of these
71 | resources. We recommend the following (at minimum) for anonymous and
72 | authenticated users:
73 |
74 | ```
75 | Access GET on Content resource
76 | Access GET on User resource
77 | ```
78 |
79 | ### 2. Angular JS Setup
80 |
81 | install `jdrupal.js` and `angular-drupal.js`. If using bower:
82 |
83 | `bower install --save angular-drupal#8.x-1.x`
84 |
85 | As usual, be sure to include the `jdrupal.js` and `angular-drupal.js` file in your app. This typically is included via the `index.html` file somewhere after you include the
86 | `angular.js` file:
87 |
88 | ```
89 |
90 |
91 | ```
92 |
93 | The `angular-drupal` module comes with an Angular JS service called `drupal`. You can
94 | include this service throughout your app using Angular's dependency injection
95 | mechanism.
96 |
97 | The simple app, listed above, injects the `drupal` service into the app's `run`
98 | function. Then when the app runs it loads `node # 123` from Drupal and then
99 | alerts the node's title.
100 |
101 | Notice how we used a `config` function on the `angular-drupal` module in the
102 | simple app to provide the URL to our Drupal site, as well as the machine name of
103 | the Services endpoint. Without this, the module won't know how to connect to
104 | our Drupal site, so this must be added to our app as in the example above.
105 |
106 | ## Usage
107 |
108 | See the [jDrupal docs](http://jdrupal.easystreet3.com/) for more examples and the full documentation. To use in Angular, inject the `drupal` service into your code as usual and replace `jDrupal` with `drupal`.
109 |
110 | ### AUTHENTICATION
111 |
112 | #### CONNECT
113 | ```
114 | drupal.connect().then(function() {
115 | var user = jDrupal.currentUser();
116 | var msg = user.isAuthenticated() ?
117 | 'Hello ' + user.getAccountName() : 'Hello Anonymous User';
118 | alert(msg);
119 | });
120 | ```
121 |
122 | ### VIEWS
123 |
124 | First, set up a standard REST export for your view in your Drupal 8 site. Then, in your Angular code you can use something like this to query the view:
125 |
126 | ```
127 | var path = '/api/routes?rating_yds=5.2'; // The Drupal path to the Views JSON page display.
128 | drupal.viewsLoad(path).then(function(view) {
129 | var results = view.getResults();
130 | angular.forEach(results, function(row, i) {
131 | // Do something with with the result item
132 | console.log(row);
133 | });
134 | });
135 | ```
136 |
--------------------------------------------------------------------------------
/angular-drupal:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Globals
4 | #APP_MODULES_DIRECTORY="app/modules"
5 | #APP_MODULES_CUSTOM_DIRECTORY="$APP_MODULES_DIRECTORY/custom"
6 |
7 | function angular_drupal_install() {
8 | cd app
9 | mkdir bower_components
10 | cd bower_components
11 | mkdir angular
12 | cd angular/
13 | wget https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js
14 | mv angular.min.js angular.js
15 | cd ../
16 | mkdir angular-route
17 | cd angular-route/
18 | wget https://code.angularjs.org/1.4.2/angular-route.min.js
19 | mv angular-route.min.js angular-route.js
20 | cd ../
21 | mkdir angular-resource
22 | cd angular-resource/
23 | wget https://code.angularjs.org/1.4.2/angular-resource.min.js
24 | mv angular-resource.min.js angular-resource.js
25 | cd ../
26 | mkdir angular-mocks
27 | cd angular-mocks/
28 | wget https://code.angularjs.org/1.4.2/angular-mocks.js
29 | cd ../
30 | mkdir angular-drupal
31 | cd angular-drupal
32 | ln -s ../../../src/angular-drupal.js angular-drupal.js
33 | }
34 |
35 |
36 | case "$1" in
37 | install) angular_drupal_install;;
38 | -*) usage "bad argument $1";;
39 | esac
40 |
41 |
--------------------------------------------------------------------------------
/app/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "cwd": "..",
3 | "directory": "app/bower_components"
4 | }
5 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularDrupalApp', ['angular-drupal']).
4 | run(['drupal', function(drupal) {
5 |
6 | // Use drupal here...
7 | drupal.nodeLoad(1).then(function(node) {
8 | console.log(node.getTitle());
9 | });
10 | }]);
11 |
12 | // Angular Drupal Configuration Settings
13 | angular.module('angular-drupal').config(function($provide) {
14 |
15 | $provide.value('drupalSettings', {
16 | sitePath: 'http://example.com',
17 | });
18 |
19 | });
20 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Angular Drupal App
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-drupal",
3 | "version": "0.0.6",
4 | "homepage": "https://github.com/kentr/angular-drupal",
5 | "authors": [
6 | "Tyler Frankenstein ",
7 | "Kent Richards "
8 | ],
9 | "description": "An Angular JS module for Drupal 8.",
10 | "keywords": [
11 | "angular",
12 | "drupal"
13 | ],
14 | "main": "./src/angular-drupal.js",
15 | "license": "GNU",
16 | "ignore": [
17 | "**/.*",
18 | "node_modules",
19 | "bower_components",
20 | "test",
21 | "tests"
22 | ],
23 | "dependencies": {
24 | "angular": "~1.4.x",
25 | "angular-mocks": "~1.4.x",
26 | "angular-route": "~1.4.x",
27 | "angular-resource": "~1.4.x",
28 | "jdrupal": "8.x-1.x"
29 | },
30 | "resolutions": {
31 | "angular": "~1.4.x"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/build/angular-drupal.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-drupal 2016-05-09 */
2 | angular.module("angular-drupal",[]).factory("drupal",["drupalSettings","$q",function(a,b){return jDrupal.config("sitePath",a.sitePath),jDrupal}]);
3 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Wed Jun 10 2015 11:48:47 GMT-0400 (EDT)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['jasmine'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'app/bower_components/angular/angular.js',
19 | 'app/bower_components/angular-route/angular-route.js',
20 | 'app/bower_components/angular-resource/angular-resource.js',
21 | 'app/bower_components/angular-mocks/angular-mocks.js',
22 | 'app/bower_components/angular-drupal/angular-drupal.js',
23 | 'src/*.js',
24 | 'tests/DrupalSpec.js'
25 | ],
26 |
27 |
28 | // list of files to exclude
29 | exclude: [
30 | ],
31 |
32 |
33 | // preprocess matching files before serving them to the browser
34 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
35 | preprocessors: {
36 | },
37 |
38 |
39 | // test results reporter to use
40 | // possible values: 'dots', 'progress'
41 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
42 | reporters: ['progress'],
43 |
44 |
45 | // web server port
46 | port: 9876,
47 |
48 |
49 | // enable / disable colors in the output (reporters and logs)
50 | colors: true,
51 |
52 |
53 | // level of logging
54 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
55 | logLevel: config.LOG_INFO,
56 |
57 |
58 | // enable / disable watching file and executing tests whenever any file changes
59 | autoWatch: true,
60 |
61 |
62 | // start these browsers
63 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
64 | browsers: ['Chrome'],
65 |
66 | plugins: [
67 | 'karma-chrome-launcher',
68 | 'karma-jasmine'
69 | ],
70 |
71 |
72 | // Continuous Integration mode
73 | // if true, Karma captures browsers, runs the tests and exits
74 | singleRun: false
75 | });
76 | };
77 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-drupal",
3 | "version": "0.0.6",
4 | "description": "An Angular JS module for Drupal 7.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/easystreet3/angular-drupal.git"
12 | },
13 | "keywords": [
14 | "angular",
15 | "drupal"
16 | ],
17 | "author": "Tyler Frankenstein (http://tylerfrankenstein.com/)",
18 | "license": "GNU",
19 | "bugs": {
20 | "url": "https://github.com/easystreet3/angular-drupal/issues"
21 | },
22 | "homepage": "https://github.com/easystreet3/angular-drupal",
23 | "devDependencies": {
24 | "grunt": "^0.4.5",
25 | "grunt-contrib-jshint": "^0.11.2",
26 | "grunt-contrib-nodeunit": "^0.4.1",
27 | "grunt-contrib-uglify": "^0.9.1",
28 | "grunt-contrib-watch": "^0.6.1",
29 | "jasmine-core": "^2.3.4",
30 | "karma": "^0.12.36",
31 | "karma-chrome-launcher": "^0.1.12",
32 | "karma-jasmine": "^0.3.5"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/angular-drupal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The angular-drupal module.
3 | */
4 | angular.module('angular-drupal', [])
5 |
6 | /**
7 | * The drupal service for the angular-drupal module.
8 | *
9 | * @param object drupalSettings
10 | * Various settings. Change these in app.js.
11 | */
12 | .factory('drupal', ['drupalSettings', '$q', function(drupalSettings, $q) {
13 | // jDrupal is initialized globally in jdrupal.js
14 | jDrupal.config('sitePath', drupalSettings.sitePath);
15 | return jDrupal;
16 | }]);
17 |
--------------------------------------------------------------------------------
/tests/DrupalSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var sitePath, restPath;
4 |
5 | describe('drupal services', function () {
6 |
7 | var drupal, drupalSettings, $httpBackend;
8 |
9 | beforeEach(module('angular-drupal', function($provide) {
10 | $provide.value('drupalSettings', {
11 | sitePath: 'http://localhost/drupal-7',
12 | endpoint: 'drupalgap'
13 | });
14 | }));
15 |
16 | beforeEach(inject(function (_$httpBackend_, _drupal_, _drupalSettings_) {
17 | $httpBackend = _$httpBackend_;
18 | drupal = _drupal_;
19 | drupalSettings = _drupalSettings_;
20 | sitePath = drupalSettings.sitePath;
21 | restPath = drupal.sitePath + '/?q=' + drupalSettings.endpoint;
22 | }));
23 |
24 | // TOKEN
25 | // @TODO add a separate test that retrieves the token locally, if possible.
26 | it('drupal.token()', function () {
27 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
28 | drupal.token().then(function(token) {
29 | expect(token).toEqual(drupal_spec_token());
30 | });
31 | $httpBackend.flush();
32 | });
33 |
34 | // SYSTEM CONNECT
35 | it('drupal.connect() - anonymous', function () {
36 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
37 | $httpBackend.expectPOST(restPath + '/system/connect.json').respond(drupal_spec_connect_anonymous_response());
38 | drupal.connect().then(function(data) {
39 | expect(data.user.uid).toEqual(drupal_spec_connect_anonymous_response().user.uid);
40 | });
41 | $httpBackend.flush();
42 | });
43 | it('drupal.connect() - authenticated', function () {
44 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
45 | $httpBackend.expectPOST(restPath + '/system/connect.json').respond(drupal_spec_connect_authenticated_response());
46 | drupal.connect().then(function(data) {
47 | expect(data.user.uid).toEqual(drupal_spec_connect_authenticated_response().user.uid);
48 | expect(data.user.name).toEqual(drupal_spec_connect_authenticated_response().user.name);
49 | });
50 | $httpBackend.flush();
51 | });
52 |
53 | // USER REGISTER
54 | it('drupal.user_register()', function () {
55 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
56 | $httpBackend.expectPOST(restPath + '/user/register.json').respond(drupal_spec_user_register_response());
57 | drupal.user_register({ name: 'bob', mail: 'bob@hotmail.com', pass: 'secret-sauce'}).then(function(data) {
58 | expect(data.uid).toEqual(drupal_spec_user_register_response().uid);
59 | expect(data.uri).toEqual(drupal_spec_user_register_response().uri);
60 | });
61 | $httpBackend.flush();
62 | });
63 |
64 | // USER LOGIN
65 | it('drupal.user_login()', function () {
66 | $httpBackend.expectPOST(restPath + '/user/login.json').respond(drupal_spec_connect_authenticated_response());
67 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
68 | $httpBackend.expectPOST(restPath + '/system/connect.json').respond(drupal_spec_connect_authenticated_response());
69 | drupal.user_login('bob', 'secret').then(function(data) {
70 | expect(data.user.uid).toEqual(drupal_spec_connect_authenticated_response().user.uid);
71 | expect(data.user.name).toEqual(drupal_spec_connect_authenticated_response().user.name);
72 | });
73 | $httpBackend.flush();
74 | });
75 |
76 | // USER LOGOUT
77 | it('drupal.user_logout()', function () {
78 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
79 | $httpBackend.expectPOST(restPath + '/user/logout.json').respond(drupal_spec_connect_anonymous_response());
80 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
81 | $httpBackend.expectPOST(restPath + '/system/connect.json').respond(drupal_spec_connect_anonymous_response());
82 | drupal.user_logout().then(function(data) {
83 | expect(data.user.uid).toEqual(drupal_spec_connect_anonymous_response().user.uid);
84 | });
85 | $httpBackend.flush();
86 | });
87 |
88 | // ENTITY LOAD FUNCTIONS
89 |
90 | // COMMENT LOAD
91 | it('drupal.comment_load()', function () {
92 | $httpBackend.expectGET(restPath + '/comment/123.json').respond(drupal_spec_entity_load_response('comment'));
93 | drupal.comment_load(123).then(function(entity) {
94 | var key = drupal_entity_primary_key('comment');
95 | var title = drupal_entity_primary_key_title('comment');
96 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('comment')[key]);
97 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('comment')[title]);
98 | });
99 | $httpBackend.flush();
100 | });
101 |
102 | // FILE LOAD
103 | it('drupal.file_load()', function () {
104 | $httpBackend.expectGET(restPath + '/file/123.json').respond(drupal_spec_entity_load_response('file'));
105 | drupal.file_load(123).then(function(entity) {
106 | var key = drupal_entity_primary_key('file');
107 | var title = drupal_entity_primary_key_title('file');
108 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('file')[key]);
109 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('file')[title]);
110 | });
111 | $httpBackend.flush();
112 | });
113 |
114 | // NODE LOAD
115 | it('drupal.node_load()', function () {
116 | $httpBackend.expectGET(restPath + '/node/123.json').respond(drupal_spec_entity_load_response('node'));
117 | drupal.node_load(123).then(function(entity) {
118 | var key = drupal_entity_primary_key('node');
119 | var title = drupal_entity_primary_key_title('node');
120 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('node')[key]);
121 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('node')[title]);
122 | });
123 | $httpBackend.flush();
124 | });
125 |
126 | // TAXONOMY TERM LOAD
127 | it('drupal.taxonomy_term_load()', function () {
128 | $httpBackend.expectGET(restPath + '/taxonomy_term/123.json').respond(drupal_spec_entity_load_response('taxonomy_term'));
129 | drupal.taxonomy_term_load(123).then(function(entity) {
130 | var key = drupal_entity_primary_key('taxonomy_term');
131 | var title = drupal_entity_primary_key_title('taxonomy_term');
132 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('taxonomy_term')[key]);
133 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('taxonomy_term')[title]);
134 | });
135 | $httpBackend.flush();
136 | });
137 |
138 | // TAXONOMY VOCABULARY LOAD
139 | it('drupal.taxonomy_vocabulary_load()', function () {
140 | $httpBackend.expectGET(restPath + '/taxonomy_vocabulary/123.json').respond(drupal_spec_entity_load_response('taxonomy_vocabulary'));
141 | drupal.taxonomy_vocabulary_load(123).then(function(entity) {
142 | var key = drupal_entity_primary_key('taxonomy_vocabulary');
143 | var title = drupal_entity_primary_key_title('taxonomy_vocabulary');
144 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('taxonomy_vocabulary')[key]);
145 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('taxonomy_vocabulary')[title]);
146 | });
147 | $httpBackend.flush();
148 | });
149 |
150 | // USER LOAD
151 | it('drupal.user_load()', function () {
152 | $httpBackend.expectGET(restPath + '/user/123.json').respond(drupal_spec_entity_load_response('user'));
153 | drupal.user_load(123).then(function(entity) {
154 | var key = drupal_entity_primary_key('user');
155 | var title = drupal_entity_primary_key_title('user');
156 | expect(entity[key]).toEqual(drupal_spec_entity_load_response('user')[key]);
157 | expect(entity[title]).toEqual(drupal_spec_entity_load_response('user')[title]);
158 | });
159 | $httpBackend.flush();
160 | });
161 |
162 | // ENTITY SAVE FUNCTIONS
163 |
164 | // COMMENT SAVE - NEW
165 | it('drupal.comment_save() - new', function () {
166 | var comment = drupal_spec_entity_save_new_response('comment');
167 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
168 | $httpBackend.expectPOST(restPath + '/comment.json').respond(comment);
169 | drupal.comment_save(comment).then(function(entity) {
170 | var key = drupal_entity_primary_key('comment');
171 | var title = drupal_entity_primary_key_title('comment');
172 | expect(entity[key]).not.toBeNull();
173 | expect(entity[title]).toEqual(drupal_spec_entity_save_new_response('comment')[title]);
174 | });
175 | $httpBackend.flush();
176 | });
177 |
178 | // COMMENT SAVE - EXISTING
179 | it('drupal.comment_save() - existing', function () {
180 | var comment = drupal_spec_entity_save_existing_response('comment');
181 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
182 | $httpBackend.expectPUT(restPath + '/comment/' + comment.cid + '.json').respond(comment);
183 | drupal.comment_save(comment).then(function(entity) {
184 | var key = drupal_entity_primary_key('comment');
185 | var title = drupal_entity_primary_key_title('comment');
186 | expect(entity[key]).toEqual(drupal_spec_entity_save_existing_response('comment')[key]);
187 | expect(entity[title]).toEqual(drupal_spec_entity_save_existing_response('comment')[title]);
188 | });
189 | $httpBackend.flush();
190 | });
191 |
192 | // FILE SAVE - NEW
193 | it('drupal.file_save() - new', function () {
194 | var file = drupal_spec_entity_save_new_response('file');
195 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
196 | $httpBackend.expectPOST(restPath + '/file.json').respond(file);
197 | drupal.file_save(file).then(function(entity) {
198 | var key = drupal_entity_primary_key('file');
199 | var title = drupal_entity_primary_key_title('file');
200 | expect(entity[key]).not.toBeNull();
201 | expect(entity.uri).not.toBeNull();
202 | });
203 | $httpBackend.flush();
204 | });
205 |
206 | // NODE SAVE - NEW
207 | it('drupal.node_save() - new', function () {
208 | var node = drupal_spec_entity_save_new_response('node');
209 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
210 | $httpBackend.expectPOST(restPath + '/node.json').respond(node);
211 | drupal.node_save(node).then(function(entity) {
212 | var key = drupal_entity_primary_key('node');
213 | var title = drupal_entity_primary_key_title('node');
214 | expect(entity[key]).not.toBeNull();
215 | expect(entity.uri).not.toBeNull();
216 | });
217 | $httpBackend.flush();
218 | });
219 |
220 | // NODE SAVE - EXISTING
221 | it('drupal.node_save() - existing', function () {
222 | var node = drupal_spec_entity_save_existing_response('node');
223 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
224 | $httpBackend.expectPUT(restPath + '/node/' + node.nid + '.json').respond(node);
225 | drupal.node_save(node).then(function(entity) {
226 | var key = drupal_entity_primary_key('node');
227 | var title = drupal_entity_primary_key_title('node');
228 | expect(entity[key]).toEqual(drupal_spec_entity_save_existing_response('node')[key]);
229 | expect(entity.uri).not.toBeNull();
230 | });
231 | $httpBackend.flush();
232 | });
233 |
234 | // TAXONOMY TERM SAVE - NEW
235 | it('drupal.taxonomy_term_save() - new', function () {
236 | var taxonomy_term = drupal_spec_entity_save_new_response('taxonomy_term');
237 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
238 | $httpBackend.expectPOST(restPath + '/taxonomy_term.json').respond(taxonomy_term);
239 | drupal.taxonomy_term_save(taxonomy_term).then(function(entity) {
240 | var key = drupal_entity_primary_key('taxonomy_term');
241 | var title = drupal_entity_primary_key_title('taxonomy_term');
242 | expect(entity[key]).not.toBeNull();
243 | expect(entity.uri).not.toBeNull();
244 | });
245 | $httpBackend.flush();
246 | });
247 |
248 | // TAXONOMY TERM SAVE - EXISTING
249 | it('drupal.taxonomy_term_save() - existing', function () {
250 | var taxonomy_term = drupal_spec_entity_save_existing_response('taxonomy_term');
251 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
252 | $httpBackend.expectPUT(restPath + '/taxonomy_term/' + taxonomy_term.tid + '.json').respond(taxonomy_term);
253 | drupal.taxonomy_term_save(taxonomy_term).then(function(entity) {
254 | var key = drupal_entity_primary_key('taxonomy_term');
255 | var title = drupal_entity_primary_key_title('taxonomy_term');
256 | expect(entity[key]).toEqual(drupal_spec_entity_save_existing_response('taxonomy_term')[key]);
257 | expect(entity.uri).not.toBeNull();
258 | });
259 | $httpBackend.flush();
260 | });
261 |
262 | // TAXONOMY VOCABULARY SAVE - NEW
263 | it('drupal.taxonomy_vocabulary_save() - new', function () {
264 | var taxonomy_vocabulary = drupal_spec_entity_save_new_response('taxonomy_vocabulary');
265 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
266 | $httpBackend.expectPOST(restPath + '/taxonomy_vocabulary.json').respond(taxonomy_vocabulary);
267 | drupal.taxonomy_vocabulary_save(taxonomy_vocabulary).then(function(entity) {
268 | var key = drupal_entity_primary_key('taxonomy_vocabulary');
269 | var title = drupal_entity_primary_key_title('taxonomy_vocabulary');
270 | expect(entity[key]).not.toBeNull();
271 | expect(entity.uri).not.toBeNull();
272 | });
273 | $httpBackend.flush();
274 | });
275 |
276 | // TAXONOMY VOCABULARY SAVE - EXISTING
277 | it('drupal.taxonomy_vocabulary_save() - existing', function () {
278 | var taxonomy_vocabulary = drupal_spec_entity_save_existing_response('taxonomy_vocabulary');
279 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
280 | $httpBackend.expectPUT(restPath + '/taxonomy_vocabulary/' + taxonomy_vocabulary.vid + '.json').respond(taxonomy_vocabulary);
281 | drupal.taxonomy_vocabulary_save(taxonomy_vocabulary).then(function(entity) {
282 | var key = drupal_entity_primary_key('taxonomy_vocabulary');
283 | var title = drupal_entity_primary_key_title('taxonomy_vocabulary');
284 | expect(entity[key]).toEqual(drupal_spec_entity_save_existing_response('taxonomy_vocabulary')[key]);
285 | expect(entity.uri).not.toBeNull();
286 | });
287 | $httpBackend.flush();
288 | });
289 |
290 | // USER SAVE - NEW
291 | it('drupal.user_save() - new', function () {
292 | var user = drupal_spec_entity_save_new_response('user');
293 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
294 | $httpBackend.expectPOST(restPath + '/user.json').respond(user);
295 | drupal.user_save(user).then(function(entity) {
296 | var key = drupal_entity_primary_key('user');
297 | var title = drupal_entity_primary_key_title('user');
298 | expect(entity[key]).not.toBeNull();
299 | expect(entity.uri).not.toBeNull();
300 | });
301 | $httpBackend.flush();
302 | });
303 |
304 | // USER SAVE - EXISTING
305 | it('drupal.user_save() - existing', function () {
306 | var user = drupal_spec_entity_save_existing_response('user');
307 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
308 | $httpBackend.expectPUT(restPath + '/user/' + user.uid + '.json').respond(user);
309 | drupal.user_save(user).then(function(entity) {
310 | var key = drupal_entity_primary_key('user');
311 | var title = drupal_entity_primary_key_title('user');
312 | expect(entity[key]).toEqual(drupal_spec_entity_save_existing_response('user')[key]);
313 | expect(entity.uri).not.toBeNull();
314 | });
315 | $httpBackend.flush();
316 | });
317 |
318 | // ENTITY DELETE FUNCTIONS
319 |
320 | // COMMENT DELETE
321 | it('drupal.comment_delete()', function () {
322 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
323 | $httpBackend.expectDELETE(restPath + '/comment/123.json').respond(drupal_spec_entity_delete_response('comment'));
324 | drupal.comment_delete(123).then(function(data) {
325 | expect(data[0]).toEqual(drupal_spec_entity_delete_response('comment')[0]);
326 | });
327 | $httpBackend.flush();
328 | });
329 |
330 | // NODE DELETE
331 | it('drupal.node_delete()', function () {
332 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
333 | $httpBackend.expectDELETE(restPath + '/node/123.json').respond(drupal_spec_entity_delete_response('node'));
334 | drupal.node_delete(123).then(function(data) {
335 | expect(data[0]).toEqual(drupal_spec_entity_delete_response('node')[0]);
336 | });
337 | $httpBackend.flush();
338 | });
339 |
340 | // TAXONOMY TERM DELETE
341 | it('drupal.taxonomy_term_delete()', function () {
342 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
343 | $httpBackend.expectDELETE(restPath + '/taxonomy_term/123.json').respond(drupal_spec_entity_delete_response('taxonomy_term'));
344 | drupal.taxonomy_term_delete(123).then(function(data) {
345 | expect(data[0]).toEqual(drupal_spec_entity_delete_response('taxonomy_term')[0]);
346 | });
347 | $httpBackend.flush();
348 | });
349 |
350 | // TAXONOMY VOCABULARY DELETE
351 | it('drupal.taxonomy_vocabulary_delete()', function () {
352 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
353 | $httpBackend.expectDELETE(restPath + '/taxonomy_vocabulary/123.json').respond(drupal_spec_entity_delete_response('taxonomy_vocabulary'));
354 | drupal.taxonomy_vocabulary_delete(123).then(function(data) {
355 | expect(data[0]).toEqual(drupal_spec_entity_delete_response('taxonomy_vocabulary')[0]);
356 | });
357 | $httpBackend.flush();
358 | });
359 |
360 | // USER DELETE
361 | it('drupal.user_delete()', function () {
362 | $httpBackend.expectGET(drupal_spec_token_url()).respond(drupal_spec_token());
363 | $httpBackend.expectDELETE(restPath + '/user/123.json').respond(drupal_spec_entity_delete_response('user'));
364 | drupal.user_delete(123).then(function(data) {
365 | expect(data[0]).toEqual(drupal_spec_entity_delete_response('user')[0]);
366 | });
367 | $httpBackend.flush();
368 | });
369 |
370 | // ENTITY INDEX FUNCTIONS
371 |
372 | // COMMENT INDEX
373 | it('drupal.comment_index()', function () {
374 | var query = drupal_spec_entity_index_query('comment');
375 | var path = restPath + '/comment.json&' + drupal_entity_index_build_query_string(query);
376 | $httpBackend.expectGET(path).respond(drupal_spec_entity_index_response('comment'));
377 | drupal.comment_index(query).then(function(comments) {
378 | expect(comments.length).toEqual(drupal_spec_entity_index_response('comment').length);
379 | });
380 | $httpBackend.flush();
381 | });
382 |
383 | // NODE INDEX
384 | it('drupal.node_index()', function () {
385 | var query = drupal_spec_entity_index_query('node');
386 | var path = restPath + '/node.json&' + drupal_entity_index_build_query_string(query);
387 | $httpBackend.expectGET(path).respond(drupal_spec_entity_index_response('node'));
388 | drupal.node_index(query).then(function(nodes) {
389 | expect(nodes.length).toEqual(drupal_spec_entity_index_response('node').length);
390 | });
391 | $httpBackend.flush();
392 | });
393 |
394 | // TAXONOMY TERM INDEX
395 | it('drupal.taxonomy_term_index()', function () {
396 | var query = drupal_spec_entity_index_query('taxonomy_term');
397 | var path = restPath + '/taxonomy_term.json&' + drupal_entity_index_build_query_string(query);
398 | $httpBackend.expectGET(path).respond(drupal_spec_entity_index_response('taxonomy_term'));
399 | drupal.taxonomy_term_index(query).then(function(taxonomy_terms) {
400 | expect(taxonomy_terms.length).toEqual(drupal_spec_entity_index_response('taxonomy_term').length);
401 | });
402 | $httpBackend.flush();
403 | });
404 |
405 | // TAXONOMY VOCABULARY INDEX
406 | it('drupal.taxonomy_vocabulary_index()', function () {
407 | var query = drupal_spec_entity_index_query('taxonomy_vocabulary');
408 | var path = restPath + '/taxonomy_vocabulary.json&' + drupal_entity_index_build_query_string(query);
409 | $httpBackend.expectGET(path).respond(drupal_spec_entity_index_response('taxonomy_vocabulary'));
410 | drupal.taxonomy_vocabulary_index(query).then(function(taxonomy_vocabularys) {
411 | expect(taxonomy_vocabularys.length).toEqual(drupal_spec_entity_index_response('taxonomy_vocabulary').length);
412 | });
413 | $httpBackend.flush();
414 | });
415 |
416 | // USER INDEX
417 | it('drupal.user_index()', function () {
418 | var query = drupal_spec_entity_index_query('user');
419 | var path = restPath + '/user.json&' + drupal_entity_index_build_query_string(query);
420 | $httpBackend.expectGET(path).respond(drupal_spec_entity_index_response('user'));
421 | drupal.user_index(query).then(function(users) {
422 | expect(users.length).toEqual(drupal_spec_entity_index_response('user').length);
423 | });
424 | $httpBackend.flush();
425 | });
426 |
427 | });
428 |
429 | /**
430 | *
431 | */
432 | function drupal_spec_token() {
433 | try {
434 | return 'S2PwGqWxzuTQzhFeHfAIzq7AMVmnHM7W4gkaeziumvA';
435 | }
436 | catch (error) { console.log('drupal_spec_token - ' + error); }
437 | }
438 |
439 | /**
440 | *
441 | */
442 | function drupal_spec_token_url() {
443 | try {
444 | return sitePath + '/?q=services/session/token';
445 | }
446 | catch (error) { console.log('drupal_spec_token_url - ' + error); }
447 | }
448 |
449 | /**
450 | *
451 | */
452 | function drupal_spec_connect_anonymous_response() {
453 | try {
454 | return {
455 | user: {
456 | uid: 0
457 | }
458 | };
459 | }
460 | catch (error) { console.log('drupal_spec_connect_anonymous_response - ' + error); }
461 | }
462 |
463 | /**
464 | *
465 | */
466 | function drupal_spec_connect_authenticated_response() {
467 | try {
468 | return {
469 | user: {
470 | uid: 1,
471 | name: 'dries'
472 | }
473 | };
474 | }
475 | catch (error) { console.log('drupal_spec_connect_authenticated_response - ' + error); }
476 | }
477 |
478 | /**
479 | *
480 | */
481 | function drupal_spec_user_register_response() {
482 | try {
483 | return {
484 | uid: 2,
485 | uri: 'http://localhost/drupal-7/drupalgap/user/2'
486 | }
487 | }
488 | catch (error) { console.log('drupal_spec_user_register_response - ' + error); }
489 | }
490 |
491 | /**
492 | *
493 | */
494 | function drupal_spec_entity_load_response(entity_type) {
495 | try {
496 | var entity = {};
497 | entity[drupal_entity_primary_key(entity_type)] = 123;
498 | entity[drupal_entity_primary_key_title(entity_type)] = 'Hello world';
499 | return entity;
500 | }
501 | catch (error) { console.log('drupal_spec_entity_load_response - ' + error); }
502 | }
503 |
504 | /**
505 | *
506 | */
507 | function drupal_spec_entity_save_new_response(entity_type) {
508 | try {
509 | var entity = {};
510 | entity[drupal_entity_primary_key_title(entity_type)] = 'Hello world';
511 | switch (entity_type) {
512 | case 'comment':
513 | entity.nid = 123;
514 | break;
515 | case 'node':
516 | entity.type = 'article';
517 | entity.language = 'und';
518 | break;
519 | }
520 | return entity;
521 | }
522 | catch (error) { console.log('drupal_spec_entity_load_response - ' + error); }
523 | }
524 |
525 | /**
526 | *
527 | */
528 | function drupal_spec_entity_save_existing_response(entity_type) {
529 | try {
530 | var entity = drupal_spec_entity_save_new_response(entity_type);
531 | entity[drupal_entity_primary_key(entity_type)] = 123;
532 | entity[drupal_entity_primary_key_title(entity_type)] = 'Goodbye world';
533 | return entity;
534 | }
535 | catch (error) { console.log('drupal_spec_entity_save_existing_response - ' + error); }
536 | }
537 |
538 | /**
539 | *
540 | */
541 | function drupal_spec_entity_delete_response(entity_type) {
542 | try {
543 | return [true];
544 | }
545 | catch (error) { console.log('drupal_spec_entity_delete_response - ' + error); }
546 | }
547 |
548 | /**
549 | *
550 | */
551 | function drupal_spec_entity_index_query(entity_type) {
552 | try {
553 | var query = { };
554 | switch (entity_type) {
555 | case 'comment':
556 | query = {
557 | parameters: {
558 | 'nid': 123
559 | }
560 | };
561 | break;
562 | case 'node':
563 | query = {
564 | parameters: {
565 | 'type': 'article'
566 | }
567 | };
568 | break;
569 | case 'taxonomy_term':
570 | query = {
571 | parameters: {
572 | 'vid': 1
573 | }
574 | };
575 | break;
576 | case 'taxonomy_vocabulary':
577 | query = {
578 | parameters: {
579 | 'name': 'tags'
580 | }
581 | };
582 | break;
583 | case 'user':
584 | break;
585 | default:
586 | console.log('drupal_spec_entity_index_query - unsupported entity type: ' + entity_type);
587 | break;
588 | }
589 | return query;
590 | }
591 | catch (error) { console.log('drupal_spec_entity_index_query - ' + error); }
592 | }
593 |
594 | /**
595 | *
596 | */
597 | function drupal_spec_entity_index_response(entity_type) {
598 | try {
599 | var entities = [];
600 | for (var i = 0; i < 10; i++) {
601 | entities.push(drupal_spec_entity_save_existing_response(entity_type));
602 | }
603 | return entities;
604 | }
605 | catch (error) { console.log('drupal_spec_entity_delete_response - ' + error); }
606 | }
607 |
608 |
--------------------------------------------------------------------------------
/tests/support/jasmine.json:
--------------------------------------------------------------------------------
1 | {
2 | "spec_dir": "tests",
3 | "spec_files": [
4 | "*[sS]pec.js"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------