ankh 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/.gitignore +18 -0
  2. data/{spec/spec.opts → .rspec} +0 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +4 -2
  6. data/README.rdoc +15 -5
  7. data/Rakefile +6 -84
  8. data/ankh.gemspec +20 -67
  9. data/lib/..rb +5 -0
  10. data/lib/ankh.rb +4 -6
  11. data/lib/ankh/model.rb +18 -10
  12. data/lib/ankh/question.rb +1 -1
  13. data/lib/ankh/railtie.rb +8 -0
  14. data/lib/ankh/validations/{human.rb → human_validator.rb} +0 -12
  15. data/lib/ankh/version.rb +3 -0
  16. data/spec/ankh/model_spec.rb +10 -7
  17. data/spec/dummy/Rakefile +7 -0
  18. data/spec/dummy/api_docs/api_authentication.markdown +70 -0
  19. data/spec/dummy/api_docs/api_user_creates_user.markdown +1170 -0
  20. data/spec/dummy/api_docs/partner_creation.markdown +78 -0
  21. data/spec/dummy/api_docs/topic_creation.markdown +76 -0
  22. data/spec/dummy/api_docs/user_creation.markdown +31 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  26. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  27. data/{features/step_definitions/ankh_steps.rb → spec/dummy/app/mailers/.gitkeep} +0 -0
  28. data/spec/dummy/app/models/.gitkeep +0 -0
  29. data/spec/dummy/app/views/devise/confirmations/new.html.erb +15 -0
  30. data/spec/dummy/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  31. data/spec/dummy/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  32. data/spec/dummy/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  33. data/spec/dummy/app/views/devise/passwords/edit.html.erb +19 -0
  34. data/spec/dummy/app/views/devise/passwords/new.html.erb +15 -0
  35. data/spec/dummy/app/views/devise/registrations/edit.html.erb +22 -0
  36. data/spec/dummy/app/views/devise/registrations/new.html.erb +20 -0
  37. data/spec/dummy/app/views/devise/sessions/new.html.erb +15 -0
  38. data/spec/dummy/app/views/devise/sessions/new.mobile.erb +14 -0
  39. data/spec/dummy/app/views/devise/shared/_links.erb +25 -0
  40. data/spec/dummy/app/views/devise/unlocks/new.html.erb +15 -0
  41. data/spec/dummy/config.ru +4 -0
  42. data/spec/dummy/config/application.rb +45 -0
  43. data/spec/dummy/config/boot.rb +10 -0
  44. data/spec/dummy/config/database.yml +20 -0
  45. data/spec/dummy/config/environment.rb +5 -0
  46. data/spec/dummy/config/environments/development.rb +30 -0
  47. data/spec/dummy/config/environments/production.rb +60 -0
  48. data/spec/dummy/config/environments/test.rb +39 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/inflections.rb +10 -0
  51. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  52. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  53. data/spec/dummy/config/initializers/session_store.rb +8 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +5 -0
  56. data/spec/dummy/config/routes.rb +3 -0
  57. data/spec/dummy/db/development.sqlite3 +0 -0
  58. data/spec/dummy/db/schema.rb +188 -0
  59. data/spec/dummy/db/test.sqlite3 +0 -0
  60. data/spec/dummy/lib/assets/.gitkeep +0 -0
  61. data/spec/dummy/public/404.html +26 -0
  62. data/spec/dummy/public/422.html +26 -0
  63. data/spec/dummy/public/500.html +26 -0
  64. data/spec/dummy/public/favicon.ico +0 -0
  65. data/spec/dummy/script/rails +6 -0
  66. data/spec/spec_helper.rb +10 -14
  67. metadata +205 -130
  68. data/features/ankh.feature +0 -9
  69. data/features/support/env.rb +0 -4
  70. data/lib/ankh/rails/legacy.rb +0 -41
  71. data/spec/support/active_record_spec_helper.rb +0 -44
@@ -0,0 +1,70 @@
1
+ ---
2
+ layout: page
3
+ title: API Authentication
4
+ comments: false
5
+ sharing: false
6
+ footer: true
7
+ ---
8
+
9
+ ## allows users to retrieve partner data when a valid api token is specified ##
10
+
11
+ Sample Request URI:
12
+
13
+ ```
14
+ GET /api/partners/acme.json?api_token=FASDFGXA9
15
+ ```
16
+
17
+ Sample Response:
18
+
19
+ Status: 200
20
+
21
+ ```javascript
22
+ {
23
+ "created_at": "2011-12-12T22:34:30Z",
24
+ "id": 547,
25
+ "idea_rating_system_id": null,
26
+ "intro_text": null,
27
+ "name": "acme",
28
+ "plan_tier": "freemium",
29
+ "rating_system_id": 996,
30
+ "subdomain": "acme",
31
+ "updated_at": "2011-12-12T22:34:30Z"
32
+ }
33
+ ```
34
+
35
+ ## denies access to the api when an invalid token is specified ##
36
+
37
+ Sample Request URI:
38
+
39
+ ```
40
+ GET /unauthenticated?api_token=431415421451
41
+ ```
42
+
43
+ Sample Response:
44
+
45
+ Status: 401
46
+
47
+ ```javascript
48
+ {
49
+ "error": "Invalid authentication token."
50
+ }
51
+ ```
52
+
53
+ ## denies access to the api when a token is not specified ##
54
+
55
+ Sample Request URI:
56
+
57
+ ```
58
+ GET /unauthenticated
59
+ ```
60
+
61
+ Sample Response:
62
+
63
+ Status: 401
64
+
65
+ ```javascript
66
+ {
67
+ "error": "You need to sign in or sign up before continuing."
68
+ }
69
+ ```
70
+
@@ -0,0 +1,1170 @@
1
+ ## create an invalid user ##
2
+
3
+ Sample Request URI:
4
+
5
+ ```
6
+ POST /api/users.json?api_token=FASDFGXA15
7
+ Body:
8
+ ```
9
+
10
+ Sample Response:
11
+
12
+ Status: 422
13
+
14
+ ```javascript
15
+ {
16
+ "email": [
17
+ "can't be blank"
18
+ ],
19
+ "password": [
20
+ "can't be blank"
21
+ ]
22
+ }
23
+ ```
24
+
25
+ ## attempt to create a user with a duplicate external id ##
26
+
27
+ Sample Request URI:
28
+
29
+ ```
30
+ POST /api/users.json?api_token=FASDFGXA16
31
+ Body: user[external_id]=external_id
32
+ ```
33
+
34
+ Sample Response:
35
+
36
+ Status: 422
37
+
38
+ ```javascript
39
+ {
40
+ "external_id": [
41
+ "has already been taken"
42
+ ]
43
+ }
44
+ ```
45
+
46
+ ## create an invalid user ##
47
+
48
+ Sample Request URI:
49
+
50
+ ```
51
+ POST /api/users.json?api_token=FASDFGXA15
52
+ Body:
53
+ ```
54
+
55
+ Sample Response:
56
+
57
+ Status: 422
58
+
59
+ ```javascript
60
+ {
61
+ "email": [
62
+ "can't be blank"
63
+ ],
64
+ "password": [
65
+ "can't be blank"
66
+ ]
67
+ }
68
+ ```
69
+
70
+ ## attempt to create a user with a duplicate external id ##
71
+
72
+ Sample Request URI:
73
+
74
+ ```
75
+ POST /api/users.json?api_token=FASDFGXA16
76
+ Body: user[external_id]=external_id
77
+ ```
78
+
79
+ Sample Response:
80
+
81
+ Status: 422
82
+
83
+ ```javascript
84
+ {
85
+ "external_id": [
86
+ "has already been taken"
87
+ ]
88
+ }
89
+ ```
90
+
91
+ ## create an invalid user ##
92
+
93
+ Sample Request URI:
94
+
95
+ ```
96
+ POST /api/users.json?api_token=FASDFGXA15
97
+ Body:
98
+ ```
99
+
100
+ Sample Response:
101
+
102
+ Status: 422
103
+
104
+ ```javascript
105
+ {
106
+ "email": [
107
+ "can't be blank"
108
+ ],
109
+ "password": [
110
+ "can't be blank"
111
+ ]
112
+ }
113
+ ```
114
+
115
+ ## attempt to create a user with a duplicate external id ##
116
+
117
+ Sample Request URI:
118
+
119
+ ```
120
+ POST /api/users.json?api_token=FASDFGXA16
121
+ Body: user[external_id]=external_id
122
+ ```
123
+
124
+ Sample Response:
125
+
126
+ Status: 422
127
+
128
+ ```javascript
129
+ {
130
+ "external_id": [
131
+ "has already been taken"
132
+ ]
133
+ }
134
+ ```
135
+
136
+ ## create an invalid user ##
137
+
138
+ Sample Request URI:
139
+
140
+ ```
141
+ POST /api/users.json?api_token=FASDFGXA15
142
+ Body:
143
+ ```
144
+
145
+ Sample Response:
146
+
147
+ Status: 422
148
+
149
+ ```javascript
150
+ {
151
+ "email": [
152
+ "can't be blank"
153
+ ],
154
+ "password": [
155
+ "can't be blank"
156
+ ]
157
+ }
158
+ ```
159
+
160
+ ## attempt to create a user with a duplicate external id ##
161
+
162
+ Sample Request URI:
163
+
164
+ ```
165
+ POST /api/users.json?api_token=FASDFGXA16
166
+ Body: user[external_id]=external_id
167
+ ```
168
+
169
+ Sample Response:
170
+
171
+ Status: 422
172
+
173
+ ```javascript
174
+ {
175
+ "external_id": [
176
+ "has already been taken"
177
+ ]
178
+ }
179
+ ```
180
+
181
+ ## create an invalid user ##
182
+
183
+ Sample Request URI:
184
+
185
+ ```
186
+ POST /api/users.json?api_token=FASDFGXA15
187
+ Body:
188
+ ```
189
+
190
+ Sample Response:
191
+
192
+ Status: 422
193
+
194
+ ```javascript
195
+ {
196
+ "email": [
197
+ "can't be blank"
198
+ ],
199
+ "password": [
200
+ "can't be blank"
201
+ ]
202
+ }
203
+ ```
204
+
205
+ ## attempt to create a user with a duplicate external id ##
206
+
207
+ Sample Request URI:
208
+
209
+ ```
210
+ POST /api/users.json?api_token=FASDFGXA16
211
+ Body: user[external_id]=external_id
212
+ ```
213
+
214
+ Sample Response:
215
+
216
+ Status: 422
217
+
218
+ ```javascript
219
+ {
220
+ "external_id": [
221
+ "has already been taken"
222
+ ]
223
+ }
224
+ ```
225
+
226
+ ## create an invalid user ##
227
+
228
+ Sample Request URI:
229
+
230
+ ```
231
+ POST /api/users.json?api_token=FASDFGXA15
232
+ Body:
233
+ ```
234
+
235
+ Sample Response:
236
+
237
+ Status: 422
238
+
239
+ ```javascript
240
+ {
241
+ "email": [
242
+ "can't be blank"
243
+ ],
244
+ "password": [
245
+ "can't be blank"
246
+ ]
247
+ }
248
+ ```
249
+
250
+ ## attempt to create a user with a duplicate external id ##
251
+
252
+ Sample Request URI:
253
+
254
+ ```
255
+ POST /api/users.json?api_token=FASDFGXA16
256
+ Body: user[external_id]=external_id
257
+ ```
258
+
259
+ Sample Response:
260
+
261
+ Status: 422
262
+
263
+ ```javascript
264
+ {
265
+ "external_id": [
266
+ "has already been taken"
267
+ ]
268
+ }
269
+ ```
270
+
271
+ ## create an invalid user ##
272
+
273
+ Sample Request URI:
274
+
275
+ ```
276
+ POST /api/users.json?api_token=FASDFGXA15
277
+ Body:
278
+ ```
279
+
280
+ Sample Response:
281
+
282
+ Status: 422
283
+
284
+ ```javascript
285
+ {
286
+ "email": [
287
+ "can't be blank"
288
+ ],
289
+ "password": [
290
+ "can't be blank"
291
+ ]
292
+ }
293
+ ```
294
+
295
+ ## attempt to create a user with a duplicate external id ##
296
+
297
+ Sample Request URI:
298
+
299
+ ```
300
+ POST /api/users.json?api_token=FASDFGXA16
301
+ Body: user[external_id]=external_id
302
+ ```
303
+
304
+ Sample Response:
305
+
306
+ Status: 422
307
+
308
+ ```javascript
309
+ {
310
+ "external_id": [
311
+ "has already been taken"
312
+ ]
313
+ }
314
+ ```
315
+
316
+ ## create an invalid user ##
317
+
318
+ Sample Request URI:
319
+
320
+ ```
321
+ POST /api/users.json?api_token=FASDFGXA15
322
+ Body:
323
+ ```
324
+
325
+ Sample Response:
326
+
327
+ Status: 422
328
+
329
+ ```javascript
330
+ {
331
+ "email": [
332
+ "can't be blank"
333
+ ],
334
+ "password": [
335
+ "can't be blank"
336
+ ]
337
+ }
338
+ ```
339
+
340
+ ## attempt to create a user with a duplicate external id ##
341
+
342
+ Sample Request URI:
343
+
344
+ ```
345
+ POST /api/users.json?api_token=FASDFGXA16
346
+ Body: user[external_id]=external_id
347
+ ```
348
+
349
+ Sample Response:
350
+
351
+ Status: 422
352
+
353
+ ```javascript
354
+ {
355
+ "external_id": [
356
+ "has already been taken"
357
+ ]
358
+ }
359
+ ```
360
+
361
+ ## create an invalid user ##
362
+
363
+ Sample Request URI:
364
+
365
+ ```
366
+ POST /api/users.json?api_token=FASDFGXA15
367
+ Body:
368
+ ```
369
+
370
+ Sample Response:
371
+
372
+ Status: 422
373
+
374
+ ```javascript
375
+ {
376
+ "email": [
377
+ "can't be blank"
378
+ ],
379
+ "password": [
380
+ "can't be blank"
381
+ ]
382
+ }
383
+ ```
384
+
385
+ ## attempt to create a user with a duplicate external id ##
386
+
387
+ Sample Request URI:
388
+
389
+ ```
390
+ POST /api/users.json?api_token=FASDFGXA16
391
+ Body: user[external_id]=external_id
392
+ ```
393
+
394
+ Sample Response:
395
+
396
+ Status: 422
397
+
398
+ ```javascript
399
+ {
400
+ "external_id": [
401
+ "has already been taken"
402
+ ]
403
+ }
404
+ ```
405
+
406
+ ## create an invalid user ##
407
+
408
+ Sample Request URI:
409
+
410
+ ```
411
+ POST /api/users.json?api_token=FASDFGXA15
412
+ Body:
413
+ ```
414
+
415
+ Sample Response:
416
+
417
+ Status: 422
418
+
419
+ ```javascript
420
+ {
421
+ "email": [
422
+ "can't be blank"
423
+ ],
424
+ "password": [
425
+ "can't be blank"
426
+ ]
427
+ }
428
+ ```
429
+
430
+ ## attempt to create a user with a duplicate external id ##
431
+
432
+ Sample Request URI:
433
+
434
+ ```
435
+ POST /api/users.json?api_token=FASDFGXA16
436
+ Body: user[external_id]=external_id
437
+ ```
438
+
439
+ Sample Response:
440
+
441
+ Status: 422
442
+
443
+ ```javascript
444
+ {
445
+ "external_id": [
446
+ "has already been taken"
447
+ ]
448
+ }
449
+ ```
450
+
451
+ ## create an invalid user ##
452
+
453
+ Sample Request URI:
454
+
455
+ ```
456
+ POST /api/users.json?api_token=FASDFGXA15
457
+ Body:
458
+ ```
459
+
460
+ Sample Response:
461
+
462
+ Status: 422
463
+
464
+ ```javascript
465
+ {
466
+ "email": [
467
+ "can't be blank"
468
+ ],
469
+ "password": [
470
+ "can't be blank"
471
+ ]
472
+ }
473
+ ```
474
+
475
+ ## attempt to create a user with a duplicate external id ##
476
+
477
+ Sample Request URI:
478
+
479
+ ```
480
+ POST /api/users.json?api_token=FASDFGXA16
481
+ Body: user[external_id]=external_id
482
+ ```
483
+
484
+ Sample Response:
485
+
486
+ Status: 422
487
+
488
+ ```javascript
489
+ {
490
+ "external_id": [
491
+ "has already been taken"
492
+ ]
493
+ }
494
+ ```
495
+
496
+ ## create an invalid user ##
497
+
498
+ Sample Request URI:
499
+
500
+ ```
501
+ POST /api/users.json?api_token=FASDFGXA15
502
+ Body:
503
+ ```
504
+
505
+ Sample Response:
506
+
507
+ Status: 422
508
+
509
+ ```javascript
510
+ {
511
+ "email": [
512
+ "can't be blank"
513
+ ],
514
+ "password": [
515
+ "can't be blank"
516
+ ]
517
+ }
518
+ ```
519
+
520
+ ## attempt to create a user with a duplicate external id ##
521
+
522
+ Sample Request URI:
523
+
524
+ ```
525
+ POST /api/users.json?api_token=FASDFGXA16
526
+ Body: user[external_id]=external_id
527
+ ```
528
+
529
+ Sample Response:
530
+
531
+ Status: 422
532
+
533
+ ```javascript
534
+ {
535
+ "external_id": [
536
+ "has already been taken"
537
+ ]
538
+ }
539
+ ```
540
+
541
+ ## create an invalid user ##
542
+
543
+ Sample Request URI:
544
+
545
+ ```
546
+ POST /api/users.json?api_token=FASDFGXA15
547
+ Body:
548
+ ```
549
+
550
+ Sample Response:
551
+
552
+ Status: 422
553
+
554
+ ```javascript
555
+ {
556
+ "email": [
557
+ "can't be blank"
558
+ ],
559
+ "password": [
560
+ "can't be blank"
561
+ ]
562
+ }
563
+ ```
564
+
565
+ ## attempt to create a user with a duplicate external id ##
566
+
567
+ Sample Request URI:
568
+
569
+ ```
570
+ POST /api/users.json?api_token=FASDFGXA16
571
+ Body: user[external_id]=external_id
572
+ ```
573
+
574
+ Sample Response:
575
+
576
+ Status: 422
577
+
578
+ ```javascript
579
+ {
580
+ "external_id": [
581
+ "has already been taken"
582
+ ]
583
+ }
584
+ ```
585
+
586
+ ## create an invalid user ##
587
+
588
+ Sample Request URI:
589
+
590
+ ```
591
+ POST /api/users.json?api_token=FASDFGXA15
592
+ Body:
593
+ ```
594
+
595
+ Sample Response:
596
+
597
+ Status: 422
598
+
599
+ ```javascript
600
+ {
601
+ "email": [
602
+ "can't be blank"
603
+ ],
604
+ "password": [
605
+ "can't be blank"
606
+ ]
607
+ }
608
+ ```
609
+
610
+ ## attempt to create a user with a duplicate external id ##
611
+
612
+ Sample Request URI:
613
+
614
+ ```
615
+ POST /api/users.json?api_token=FASDFGXA16
616
+ Body: user[external_id]=external_id
617
+ ```
618
+
619
+ Sample Response:
620
+
621
+ Status: 422
622
+
623
+ ```javascript
624
+ {
625
+ "external_id": [
626
+ "has already been taken"
627
+ ]
628
+ }
629
+ ```
630
+
631
+ ## create an invalid user ##
632
+
633
+ Sample Request URI:
634
+
635
+ ```
636
+ POST /api/users.json?api_token=FASDFGXA15
637
+ Body:
638
+ ```
639
+
640
+ Sample Response:
641
+
642
+ Status: 422
643
+
644
+ ```javascript
645
+ {
646
+ "email": [
647
+ "can't be blank"
648
+ ],
649
+ "password": [
650
+ "can't be blank"
651
+ ]
652
+ }
653
+ ```
654
+
655
+ ## attempt to create a user with a duplicate external id ##
656
+
657
+ Sample Request URI:
658
+
659
+ ```
660
+ POST /api/users.json?api_token=FASDFGXA16
661
+ Body: user[external_id]=external_id
662
+ ```
663
+
664
+ Sample Response:
665
+
666
+ Status: 422
667
+
668
+ ```javascript
669
+ {
670
+ "external_id": [
671
+ "has already been taken"
672
+ ]
673
+ }
674
+ ```
675
+
676
+ ## create an invalid user ##
677
+
678
+ Sample Request URI:
679
+
680
+ ```
681
+ POST /api/users.json?api_token=FASDFGXA15
682
+ Body:
683
+ ```
684
+
685
+ Sample Response:
686
+
687
+ Status: 422
688
+
689
+ ```javascript
690
+ {
691
+ "email": [
692
+ "can't be blank"
693
+ ],
694
+ "password": [
695
+ "can't be blank"
696
+ ]
697
+ }
698
+ ```
699
+
700
+ ## attempt to create a user with a duplicate external id ##
701
+
702
+ Sample Request URI:
703
+
704
+ ```
705
+ POST /api/users.json?api_token=FASDFGXA16
706
+ Body: user[external_id]=external_id
707
+ ```
708
+
709
+ Sample Response:
710
+
711
+ Status: 422
712
+
713
+ ```javascript
714
+ {
715
+ "external_id": [
716
+ "has already been taken"
717
+ ]
718
+ }
719
+ ```
720
+
721
+ ## create an invalid user ##
722
+
723
+ Sample Request URI:
724
+
725
+ ```
726
+ POST /api/users.json?api_token=FASDFGXA15
727
+ Body:
728
+ ```
729
+
730
+ Sample Response:
731
+
732
+ Status: 422
733
+
734
+ ```javascript
735
+ {
736
+ "email": [
737
+ "can't be blank"
738
+ ],
739
+ "password": [
740
+ "can't be blank"
741
+ ]
742
+ }
743
+ ```
744
+
745
+ ## attempt to create a user with a duplicate external id ##
746
+
747
+ Sample Request URI:
748
+
749
+ ```
750
+ POST /api/users.json?api_token=FASDFGXA16
751
+ Body: user[external_id]=external_id
752
+ ```
753
+
754
+ Sample Response:
755
+
756
+ Status: 422
757
+
758
+ ```javascript
759
+ {
760
+ "external_id": [
761
+ "has already been taken"
762
+ ]
763
+ }
764
+ ```
765
+
766
+ ## create an invalid user ##
767
+
768
+ Sample Request URI:
769
+
770
+ ```
771
+ POST /api/users.json?api_token=FASDFGXA15
772
+ Body:
773
+ ```
774
+
775
+ Sample Response:
776
+
777
+ Status: 422
778
+
779
+ ```javascript
780
+ {
781
+ "email": [
782
+ "can't be blank"
783
+ ],
784
+ "password": [
785
+ "can't be blank"
786
+ ]
787
+ }
788
+ ```
789
+
790
+ ## attempt to create a user with a duplicate external id ##
791
+
792
+ Sample Request URI:
793
+
794
+ ```
795
+ POST /api/users.json?api_token=FASDFGXA16
796
+ Body: user[external_id]=external_id
797
+ ```
798
+
799
+ Sample Response:
800
+
801
+ Status: 422
802
+
803
+ ```javascript
804
+ {
805
+ "external_id": [
806
+ "has already been taken"
807
+ ]
808
+ }
809
+ ```
810
+
811
+ ## create an invalid user ##
812
+
813
+ Sample Request URI:
814
+
815
+ ```
816
+ POST /api/users.json?api_token=FASDFGXA15
817
+ Body:
818
+ ```
819
+
820
+ Sample Response:
821
+
822
+ Status: 422
823
+
824
+ ```javascript
825
+ {
826
+ "email": [
827
+ "can't be blank"
828
+ ],
829
+ "password": [
830
+ "can't be blank"
831
+ ]
832
+ }
833
+ ```
834
+
835
+ ## attempt to create a user with a duplicate external id ##
836
+
837
+ Sample Request URI:
838
+
839
+ ```
840
+ POST /api/users.json?api_token=FASDFGXA16
841
+ Body: user[external_id]=external_id
842
+ ```
843
+
844
+ Sample Response:
845
+
846
+ Status: 422
847
+
848
+ ```javascript
849
+ {
850
+ "external_id": [
851
+ "has already been taken"
852
+ ]
853
+ }
854
+ ```
855
+
856
+ ## create an invalid user ##
857
+
858
+ Sample Request URI:
859
+
860
+ ```
861
+ POST /api/users.json?api_token=FASDFGXA15
862
+ Body:
863
+ ```
864
+
865
+ Sample Response:
866
+
867
+ Status: 422
868
+
869
+ ```javascript
870
+ {
871
+ "email": [
872
+ "can't be blank"
873
+ ],
874
+ "password": [
875
+ "can't be blank"
876
+ ]
877
+ }
878
+ ```
879
+
880
+ ## attempt to create a user with a duplicate external id ##
881
+
882
+ Sample Request URI:
883
+
884
+ ```
885
+ POST /api/users.json?api_token=FASDFGXA16
886
+ Body: user[external_id]=external_id
887
+ ```
888
+
889
+ Sample Response:
890
+
891
+ Status: 422
892
+
893
+ ```javascript
894
+ {
895
+ "external_id": [
896
+ "has already been taken"
897
+ ]
898
+ }
899
+ ```
900
+
901
+ ## create an invalid user ##
902
+
903
+ Sample Request URI:
904
+
905
+ ```
906
+ POST /api/users.json?api_token=FASDFGXA15
907
+ Body:
908
+ ```
909
+
910
+ Sample Response:
911
+
912
+ Status: 422
913
+
914
+ ```javascript
915
+ {
916
+ "email": [
917
+ "can't be blank"
918
+ ],
919
+ "password": [
920
+ "can't be blank"
921
+ ]
922
+ }
923
+ ```
924
+
925
+ ## attempt to create a user with a duplicate external id ##
926
+
927
+ Sample Request URI:
928
+
929
+ ```
930
+ POST /api/users.json?api_token=FASDFGXA16
931
+ Body: user[external_id]=external_id
932
+ ```
933
+
934
+ Sample Response:
935
+
936
+ Status: 422
937
+
938
+ ```javascript
939
+ {
940
+ "external_id": [
941
+ "has already been taken"
942
+ ]
943
+ }
944
+ ```
945
+
946
+ ## create an invalid user ##
947
+
948
+ Sample Request URI:
949
+
950
+ ```
951
+ POST /api/users.json?api_token=FASDFGXA15
952
+ Body:
953
+ ```
954
+
955
+ Sample Response:
956
+
957
+ Status: 422
958
+
959
+ ```javascript
960
+ {
961
+ "email": [
962
+ "can't be blank"
963
+ ],
964
+ "password": [
965
+ "can't be blank"
966
+ ]
967
+ }
968
+ ```
969
+
970
+ ## attempt to create a user with a duplicate external id ##
971
+
972
+ Sample Request URI:
973
+
974
+ ```
975
+ POST /api/users.json?api_token=FASDFGXA16
976
+ Body: user[external_id]=external_id
977
+ ```
978
+
979
+ Sample Response:
980
+
981
+ Status: 422
982
+
983
+ ```javascript
984
+ {
985
+ "external_id": [
986
+ "has already been taken"
987
+ ]
988
+ }
989
+ ```
990
+
991
+ ## create an invalid user ##
992
+
993
+ Sample Request URI:
994
+
995
+ ```
996
+ POST /api/users.json?api_token=FASDFGXA15
997
+ Body:
998
+ ```
999
+
1000
+ Sample Response:
1001
+
1002
+ Status: 422
1003
+
1004
+ ```javascript
1005
+ {
1006
+ "email": [
1007
+ "can't be blank"
1008
+ ],
1009
+ "password": [
1010
+ "can't be blank"
1011
+ ]
1012
+ }
1013
+ ```
1014
+
1015
+ ## attempt to create a user with a duplicate external id ##
1016
+
1017
+ Sample Request URI:
1018
+
1019
+ ```
1020
+ POST /api/users.json?api_token=FASDFGXA16
1021
+ Body: user[external_id]=external_id
1022
+ ```
1023
+
1024
+ Sample Response:
1025
+
1026
+ Status: 422
1027
+
1028
+ ```javascript
1029
+ {
1030
+ "external_id": [
1031
+ "has already been taken"
1032
+ ]
1033
+ }
1034
+ ```
1035
+
1036
+ ## create an invalid user ##
1037
+
1038
+ Sample Request URI:
1039
+
1040
+ ```
1041
+ POST /api/users.json?api_token=FASDFGXA15
1042
+ Body:
1043
+ ```
1044
+
1045
+ Sample Response:
1046
+
1047
+ Status: 422
1048
+
1049
+ ```javascript
1050
+ {
1051
+ "email": [
1052
+ "can't be blank"
1053
+ ],
1054
+ "password": [
1055
+ "can't be blank"
1056
+ ]
1057
+ }
1058
+ ```
1059
+
1060
+ ## attempt to create a user with a duplicate external id ##
1061
+
1062
+ Sample Request URI:
1063
+
1064
+ ```
1065
+ POST /api/users.json?api_token=FASDFGXA16
1066
+ Body: user[external_id]=external_id
1067
+ ```
1068
+
1069
+ Sample Response:
1070
+
1071
+ Status: 422
1072
+
1073
+ ```javascript
1074
+ {
1075
+ "external_id": [
1076
+ "has already been taken"
1077
+ ]
1078
+ }
1079
+ ```
1080
+
1081
+ ## create an invalid user ##
1082
+
1083
+ Sample Request URI:
1084
+
1085
+ ```
1086
+ POST /api/users.json?api_token=FASDFGXA15
1087
+ Body:
1088
+ ```
1089
+
1090
+ Sample Response:
1091
+
1092
+ Status: 422
1093
+
1094
+ ```javascript
1095
+ {
1096
+ "email": [
1097
+ "can't be blank"
1098
+ ],
1099
+ "password": [
1100
+ "can't be blank"
1101
+ ]
1102
+ }
1103
+ ```
1104
+
1105
+ ## attempt to create a user with a duplicate external id ##
1106
+
1107
+ Sample Request URI:
1108
+
1109
+ ```
1110
+ POST /api/users.json?api_token=FASDFGXA16
1111
+ Body: user[external_id]=external_id
1112
+ ```
1113
+
1114
+ Sample Response:
1115
+
1116
+ Status: 422
1117
+
1118
+ ```javascript
1119
+ {
1120
+ "external_id": [
1121
+ "has already been taken"
1122
+ ]
1123
+ }
1124
+ ```
1125
+
1126
+ ## create an invalid user ##
1127
+
1128
+ Sample Request URI:
1129
+
1130
+ ```
1131
+ POST /api/users.json?api_token=FASDFGXA15
1132
+ Body:
1133
+ ```
1134
+
1135
+ Sample Response:
1136
+
1137
+ Status: 422
1138
+
1139
+ ```javascript
1140
+ {
1141
+ "email": [
1142
+ "can't be blank"
1143
+ ],
1144
+ "password": [
1145
+ "can't be blank"
1146
+ ]
1147
+ }
1148
+ ```
1149
+
1150
+ ## attempt to create a user with a duplicate external id ##
1151
+
1152
+ Sample Request URI:
1153
+
1154
+ ```
1155
+ POST /api/users.json?api_token=FASDFGXA16
1156
+ Body: user[external_id]=external_id
1157
+ ```
1158
+
1159
+ Sample Response:
1160
+
1161
+ Status: 422
1162
+
1163
+ ```javascript
1164
+ {
1165
+ "external_id": [
1166
+ "has already been taken"
1167
+ ]
1168
+ }
1169
+ ```
1170
+