ankh 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+