usman 0.2.3 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/usman/api/v1/base_controller.rb +15 -0
- data/app/controllers/usman/api/v1/docs_base_controller.rb +25 -0
- data/app/controllers/usman/api/v1/docs_controller.rb +165 -0
- data/app/controllers/usman/api/v1/profile_controller.rb +60 -0
- data/app/controllers/usman/api/v1/registrations_controller.rb +159 -0
- data/app/controllers/usman/registration_devices_controller.rb +141 -0
- data/app/controllers/usman/registrations_controller.rb +68 -0
- data/app/helpers/usman/api_helper.rb +21 -36
- data/app/helpers/usman/authentication_helper.rb +1 -1
- data/app/models/device.rb +30 -3
- data/app/models/registration.rb +12 -3
- data/app/models/user.rb +54 -4
- data/app/services/usman/mobile_registration_service.rb +3 -5
- data/app/views/kuppayam/api/docs/_navigation.html.erb +43 -0
- data/app/views/usman/api/v1/docs/register/_neg_case_1.html.erb +46 -0
- data/app/views/usman/api/v1/docs/register/_neg_case_2.html.erb +39 -0
- data/app/views/usman/api/v1/docs/register/_neg_case_3.html.erb +47 -0
- data/app/views/usman/api/v1/docs/register/_pos_case_1.html.erb +65 -0
- data/app/views/usman/api/v1/docs/resend_otp/_neg_case_1.html.erb +30 -0
- data/app/views/usman/api/v1/docs/resend_otp/_pos_case_1.html.erb +31 -0
- data/app/views/usman/api/v1/docs/verify_otp/_neg_case_1.html.erb +34 -0
- data/app/views/usman/api/v1/docs/verify_otp/_neg_case_2.html.erb +39 -0
- data/app/views/usman/api/v1/docs/verify_otp/_neg_case_3.html.erb +33 -0
- data/app/views/usman/api/v1/docs/verify_otp/_pos_case_1.html.erb +35 -0
- data/app/views/usman/registration_devices/_form.html.erb +24 -0
- data/app/views/usman/registration_devices/_index.html.erb +80 -0
- data/app/views/usman/registration_devices/_row.html.erb +34 -0
- data/app/views/usman/registrations/_form.html.erb +23 -0
- data/app/views/usman/registrations/_index.html.erb +60 -0
- data/app/views/usman/registrations/_row.html.erb +24 -0
- data/app/views/usman/registrations/_show.html.erb +112 -0
- data/app/views/usman/registrations/index.html.erb +47 -0
- data/config/locales/usman/api.ar.yml +43 -0
- data/config/locales/usman/api.en.yml +43 -0
- data/config/locales/usman/authentication.ar.yml +14 -14
- data/config/locales/usman/authentication.en.yml +15 -18
- data/config/routes.rb +28 -9
- data/db/migrate/20170904080436_add_tac_accepted_at_to_devices.rb +5 -0
- data/db/migrate/20170905041104_add_gender_to_users.rb +6 -0
- data/lib/usman/version.rb +1 -1
- metadata +36 -15
- data/app/controllers/api/v1/base_controller.rb +0 -13
- data/app/controllers/api/v1/registrations_controller.rb +0 -115
- data/app/controllers/usman/docs_controller.rb +0 -41
- data/app/views/usman/docs/index.html.erb +0 -502
- data/app/views/usman/docs/register.html.erb +0 -0
- data/config/locales/usman/general.ar.yml +0 -5
- data/config/locales/usman/general.en.yml +0 -5
- data/config/locales/usman/mobile_registration.ar.yml +0 -26
- data/config/locales/usman/mobile_registration.en.yml +0 -26
@@ -1,11 +1,17 @@
|
|
1
1
|
module Usman
|
2
2
|
module ApiHelper
|
3
|
-
|
4
3
|
def current_user
|
5
4
|
# Return if @current_user is already initialized else check if the user exists with the auth token present in request header
|
6
5
|
@current_user ||= authenticate_with_http_token { |token, options| User.find_by(auth_token: token)}
|
7
6
|
end
|
8
7
|
|
8
|
+
def current_device
|
9
|
+
# Return if @current_device is already initialized else check if the device exists with the api token present in request header
|
10
|
+
@current_device ||= authenticate_with_http_token { |token, options| Device.find_by(api_token: token)}
|
11
|
+
@current_registration = @current_device.registration if @current_device
|
12
|
+
@current_user = @current_registration.user if @current_registration
|
13
|
+
end
|
14
|
+
|
9
15
|
def require_auth_token
|
10
16
|
current_user
|
11
17
|
unless @current_user
|
@@ -18,6 +24,20 @@ module Usman
|
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
27
|
+
def require_api_token
|
28
|
+
current_device
|
29
|
+
unless @current_device
|
30
|
+
proc_code = Proc.new do
|
31
|
+
set_notification_messages("authentication.permission_denied", :error)
|
32
|
+
raise AuthenticationError
|
33
|
+
end
|
34
|
+
render_json_response(proc_code)
|
35
|
+
return
|
36
|
+
else
|
37
|
+
@current_user = @current_device.try(:registration).try(:user)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
21
41
|
def require_super_admin_auth_token
|
22
42
|
current_user
|
23
43
|
unless @current_user && @current_user.is_super_admin?
|
@@ -41,40 +61,5 @@ module Usman
|
|
41
61
|
return
|
42
62
|
end
|
43
63
|
end
|
44
|
-
|
45
|
-
def embed_stack_in_json_response?
|
46
|
-
return true if Rails.env.development?
|
47
|
-
Rails.env.production? && ["true", "t", "1", "yes"].include?(params[:debug].to_s.downcase.strip)
|
48
|
-
end
|
49
|
-
|
50
|
-
## This method will accept a proc, execute it and render the json
|
51
|
-
def render_json_response(proc_code)
|
52
|
-
|
53
|
-
begin
|
54
|
-
proc_code.call
|
55
|
-
@success = @success == false ? (false) : (true)
|
56
|
-
rescue Exception => e
|
57
|
-
@success = false
|
58
|
-
@errors = {
|
59
|
-
heading: I18n.translate("general.unexpected_failure.heading"),
|
60
|
-
message: I18n.translate("general.unexpected_failure.message"),
|
61
|
-
details: e.message,
|
62
|
-
stacktrace: (embed_stack_in_json_response? ? e.backtrace : nil)
|
63
|
-
}
|
64
|
-
end
|
65
|
-
@status ||= 200
|
66
|
-
|
67
|
-
response_hash = {success: @success}
|
68
|
-
response_hash[:alert] = @alert unless @alert.blank?
|
69
|
-
response_hash[:data] = @data unless @data.blank?
|
70
|
-
response_hash[:errors] = @errors unless @errors.blank?
|
71
|
-
|
72
|
-
response_hash[:total_data] = @total_data unless @total_data.blank?
|
73
|
-
response_hash[:per_page] = @per_page unless @per_page.blank?
|
74
|
-
response_hash[:current_page] = @current_page unless @current_page.blank?
|
75
|
-
|
76
|
-
render status: @status, json: response_hash
|
77
|
-
return
|
78
|
-
end
|
79
64
|
end
|
80
65
|
end
|
@@ -7,7 +7,7 @@ module Usman
|
|
7
7
|
# Return if @current_user is already initialized else check if the user exists with the auth token present in request header
|
8
8
|
@current_user ||= authenticate_with_http_token { |token, options| User.find_by(auth_token: token)}
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
# Returns the default URL to which the system should redirect the user after successful authentication
|
12
12
|
def default_redirect_url_after_sign_in
|
13
13
|
main_app.user_landing_url
|
data/app/models/device.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Device < ApplicationRecord
|
2
2
|
|
3
3
|
# Constants
|
4
|
-
EXCLUDED_JSON_ATTRIBUTES = [:last_accessed_at, :last_accessed_api, :otp, :otp_sent_at, :api_token, :token_created_at, :status, :created_at, :updated_at]
|
4
|
+
EXCLUDED_JSON_ATTRIBUTES = [:last_accessed_at, :last_accessed_api, :otp, :otp_sent_at, :api_token, :token_created_at, :status, :tac_accepted_at, :created_at, :updated_at]
|
5
5
|
|
6
6
|
PENDING = "pending"
|
7
7
|
VERIFIED = "verified"
|
@@ -71,7 +71,8 @@ class Device < ApplicationRecord
|
|
71
71
|
#options[:include] ||= []
|
72
72
|
#options[:methods] = []
|
73
73
|
#options[:methods] << :profile_image
|
74
|
-
super(options)
|
74
|
+
json = super(options)
|
75
|
+
Hash[*json.map{|k, v| [k, v || ""]}.flatten]
|
75
76
|
end
|
76
77
|
|
77
78
|
# Status Methods
|
@@ -154,7 +155,7 @@ class Device < ApplicationRecord
|
|
154
155
|
|
155
156
|
# Check if this OTP was already verified
|
156
157
|
if !self.otp_verified_at.blank?
|
157
|
-
validation_errors[:otp_verified_at] = "This OTP was already used
|
158
|
+
validation_errors[:otp_verified_at] = "This OTP was already used"
|
158
159
|
return false, validation_errors
|
159
160
|
end
|
160
161
|
|
@@ -197,6 +198,32 @@ class Device < ApplicationRecord
|
|
197
198
|
return true
|
198
199
|
end
|
199
200
|
|
201
|
+
def accept_tac(tac, dialing_prefix, mobile_number)
|
202
|
+
|
203
|
+
# Validate OTP and other parameters
|
204
|
+
validation_errors = {}
|
205
|
+
|
206
|
+
# Check if terms and conditions was accepted
|
207
|
+
unless ["true", "yes", "t", "y"].include?(tac.to_s.downcase)
|
208
|
+
validation_errors[:terms_and_conditions] = "T&C should be true"
|
209
|
+
return false, validation_errors
|
210
|
+
end
|
211
|
+
|
212
|
+
validation_errors[:mobile_number] = "doesn't match with our database" unless self.registration.mobile_number.to_s == mobile_number.to_s
|
213
|
+
validation_errors[:dialing_prefix] = "doesn't match with our database" unless self.registration.dialing_prefix.to_s == dialing_prefix.to_s
|
214
|
+
|
215
|
+
return false, validation_errors unless validation_errors.empty?
|
216
|
+
|
217
|
+
# Create API Token if OTP is verified
|
218
|
+
self.tac_accepted_at = Time.now
|
219
|
+
self.save
|
220
|
+
|
221
|
+
self.verify!
|
222
|
+
self.registration.verify!
|
223
|
+
|
224
|
+
return true, {}
|
225
|
+
end
|
226
|
+
|
200
227
|
# Other Methods
|
201
228
|
# -------------
|
202
229
|
|
data/app/models/registration.rb
CHANGED
@@ -36,8 +36,8 @@ class Registration < ApplicationRecord
|
|
36
36
|
# == Examples
|
37
37
|
# >>> registration.search(query)
|
38
38
|
# => ActiveRecord::Relation object
|
39
|
-
scope :search, lambda {|query| joins("
|
40
|
-
where("LOWER(mobile_number) LIKE LOWER('%#{query}%') OR
|
39
|
+
scope :search, lambda {|query| joins("LEFT JOIN users on users.id = registrations.user_id").
|
40
|
+
where("LOWER(registrations.mobile_number) LIKE LOWER('%#{query}%') OR
|
41
41
|
LOWER(users.name) LIKE LOWER('%#{query}%')")}
|
42
42
|
scope :status, lambda { |status| where("LOWER(status)='#{status}'") }
|
43
43
|
|
@@ -54,7 +54,8 @@ class Registration < ApplicationRecord
|
|
54
54
|
#options[:include] ||= []
|
55
55
|
#options[:methods] = []
|
56
56
|
#options[:methods] << :profile_image
|
57
|
-
super(options)
|
57
|
+
json = super(options)
|
58
|
+
Hash[*json.map{|k, v| [k, v || ""]}.flatten]
|
58
59
|
end
|
59
60
|
|
60
61
|
# Status Methods
|
@@ -115,5 +116,13 @@ class Registration < ApplicationRecord
|
|
115
116
|
def display_name
|
116
117
|
"#{self.dialing_prefix} #{self.mobile_number}"
|
117
118
|
end
|
119
|
+
|
120
|
+
# * Return city, country or just country if there is no city
|
121
|
+
# == Examples
|
122
|
+
# >>> registration.display_location
|
123
|
+
# => "Dubai, United Arab Emirates"
|
124
|
+
def display_location
|
125
|
+
[self.city.try(:name), self.country.try(:name)].compact.join(",")
|
126
|
+
end
|
118
127
|
|
119
128
|
end
|
data/app/models/user.rb
CHANGED
@@ -4,9 +4,6 @@ class User < Usman::ApplicationRecord
|
|
4
4
|
has_secure_password
|
5
5
|
|
6
6
|
# Constants
|
7
|
-
|
8
|
-
EXCLUDED_JSON_ATTRIBUTES = [:confirmation_token, :password_digest, :reset_password_token, :unlock_token, :status, :reset_password_sent_at, :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip, :confirmed_at, :confirmation_sent_at, :unconfirmed_email, :failed_attempts, :locked_at, :created_at, :updated_at]
|
9
|
-
|
10
7
|
PENDING = "pending"
|
11
8
|
APPROVED = "approved"
|
12
9
|
SUSPENDED = "suspended"
|
@@ -23,6 +20,22 @@ class User < Usman::ApplicationRecord
|
|
23
20
|
"Suspended" => SUSPENDED
|
24
21
|
}
|
25
22
|
|
23
|
+
MALE = "male"
|
24
|
+
FEMALE = "female"
|
25
|
+
NOGENDER = "nogender"
|
26
|
+
|
27
|
+
GENDER = {
|
28
|
+
MALE => "Male",
|
29
|
+
FEMALE => "Female",
|
30
|
+
NOGENDER => "No Gender"
|
31
|
+
}
|
32
|
+
|
33
|
+
GENDER_REVERSE = {
|
34
|
+
"Male" => MALE,
|
35
|
+
"Female" => FEMALE,
|
36
|
+
"No Gender" => NOGENDER
|
37
|
+
}
|
38
|
+
|
26
39
|
EXCLUDED_JSON_ATTRIBUTES = [:confirmation_token, :password_digest, :reset_password_token, :unlock_token, :status, :reset_password_sent_at, :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip, :confirmed_at, :confirmation_sent_at, :unconfirmed_email, :failed_attempts, :locked_at, :created_at, :updated_at]
|
27
40
|
DEFAULT_PASSWORD = "Password@1"
|
28
41
|
SESSION_TIME_OUT = 120.minutes
|
@@ -34,6 +47,7 @@ class User < Usman::ApplicationRecord
|
|
34
47
|
validate_password :password, condition_method: :should_validate_password?
|
35
48
|
|
36
49
|
validates :status, :presence => true, :inclusion => {:in => STATUS.keys, :presence_of => :status, :message => "%{value} is not a valid status" }
|
50
|
+
validates :gender, :inclusion => {:in => GENDER.keys, :presence_of => :status, :message => "%{value} is not a valid gender" }, :allow_nil => true
|
37
51
|
|
38
52
|
# Callbacks
|
39
53
|
before_validation :generate_auth_token
|
@@ -57,7 +71,8 @@ class User < Usman::ApplicationRecord
|
|
57
71
|
#options[:include] ||= []
|
58
72
|
#options[:methods] = []
|
59
73
|
#options[:methods] << :profile_image
|
60
|
-
super(options)
|
74
|
+
json = super(options)
|
75
|
+
Hash[*json.map{|k, v| [k, v || ""]}.flatten]
|
61
76
|
end
|
62
77
|
|
63
78
|
# Scopes Methods
|
@@ -178,6 +193,33 @@ class User < Usman::ApplicationRecord
|
|
178
193
|
self.update_attribute(:status, SUSPENDED)
|
179
194
|
end
|
180
195
|
|
196
|
+
# Gender Methods
|
197
|
+
# --------------
|
198
|
+
|
199
|
+
# * Return true if the user is male, else false.
|
200
|
+
# == Examples
|
201
|
+
# >>> user.male?
|
202
|
+
# => true
|
203
|
+
def male?
|
204
|
+
(gender == MALE)
|
205
|
+
end
|
206
|
+
|
207
|
+
# * Return true if the user is female, else false.
|
208
|
+
# == Examples
|
209
|
+
# >>> user.female?
|
210
|
+
# => true
|
211
|
+
def female?
|
212
|
+
(gender == FEMALE)
|
213
|
+
end
|
214
|
+
|
215
|
+
# * Return true if the user is nogender, else false.
|
216
|
+
# == Examples
|
217
|
+
# >>> user.nogender?
|
218
|
+
# => true
|
219
|
+
def nogender?
|
220
|
+
(gender == NOGENDER)
|
221
|
+
end
|
222
|
+
|
181
223
|
# Authentication Methods
|
182
224
|
# ----------------------
|
183
225
|
|
@@ -320,6 +362,14 @@ class User < Usman::ApplicationRecord
|
|
320
362
|
"/assets/kuppayam/defaults/user-#{size}.png"
|
321
363
|
end
|
322
364
|
|
365
|
+
def generate_username_and_password
|
366
|
+
self.username = SecureRandom.hex(4) unless self.username
|
367
|
+
# Password should contain at least one special character, integer and one upper case character
|
368
|
+
passwd = SecureRandom.hex(8) + "A@1" unless self.password
|
369
|
+
self.password = passwd
|
370
|
+
self.password_confirmation = passwd
|
371
|
+
end
|
372
|
+
|
323
373
|
private
|
324
374
|
|
325
375
|
def should_validate_password?
|
@@ -44,9 +44,8 @@ module Usman
|
|
44
44
|
|
45
45
|
if @registration.errors.any? or @device.errors.any?
|
46
46
|
errors = @registration.errors.to_hash.merge(@device.errors.to_hash)
|
47
|
-
set_error("mobile_registration.invalid_inputs", errors)
|
47
|
+
set_error("api.mobile_registration.invalid_inputs", errors)
|
48
48
|
end
|
49
|
-
|
50
49
|
end
|
51
50
|
|
52
51
|
def check_if_device_is_already_registered
|
@@ -61,7 +60,7 @@ module Usman
|
|
61
60
|
def register_new_device
|
62
61
|
|
63
62
|
if @device && @device.blocked?
|
64
|
-
set_error("mobile_registration.device_blocked")
|
63
|
+
set_error("api.mobile_registration.device_blocked")
|
65
64
|
return
|
66
65
|
end
|
67
66
|
|
@@ -96,7 +95,6 @@ module Usman
|
|
96
95
|
raise ActiveRecord::Rollback
|
97
96
|
end
|
98
97
|
end
|
99
|
-
|
100
98
|
end
|
101
99
|
|
102
100
|
def generate_new_otp
|
@@ -104,7 +102,7 @@ module Usman
|
|
104
102
|
if @device.send_otp
|
105
103
|
@device.update_attribute(:otp_sent_at, Time.now)
|
106
104
|
else
|
107
|
-
set_error("mobile_registration.otp_not_sent")
|
105
|
+
set_error("api.mobile_registration.otp_not_sent")
|
108
106
|
end
|
109
107
|
end
|
110
108
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<ul class="nav tabs-vertical">
|
2
|
+
<li class="<%= nav_active?('docs/register') ? 'active' : '' %>">
|
3
|
+
<a href="/docs/api/v1/register">
|
4
|
+
<i class="fa-globe visible-xs"></i>
|
5
|
+
<span class="hidden-xs">Register</span>
|
6
|
+
</a>
|
7
|
+
</li>
|
8
|
+
<li class="<%= nav_active?('docs/resend_otp') ? 'active' : '' %>">
|
9
|
+
<a href="/docs/api/v1/resend_otp">
|
10
|
+
<i class="fa-globe visible-xs"></i>
|
11
|
+
<span class="hidden-xs">Resend OTP</span>
|
12
|
+
</a>
|
13
|
+
</li>
|
14
|
+
<li class="<%= nav_active?('docs/verify_otp') ? 'active' : '' %>">
|
15
|
+
<a href="/docs/api/v1/verify_otp">
|
16
|
+
<i class="fa-globe visible-xs"></i>
|
17
|
+
<span class="hidden-xs">Verify OTP</span>
|
18
|
+
</a>
|
19
|
+
</li>
|
20
|
+
<li class="<%= nav_active?('docs/accept_tac') ? 'active' : '' %>">
|
21
|
+
<a href="/docs/api/v1/accept_tac">
|
22
|
+
<i class="fa-globe visible-xs"></i>
|
23
|
+
<span class="hidden-xs">Terms & Conditions</span>
|
24
|
+
</a>
|
25
|
+
</li>
|
26
|
+
<li class="<%= nav_active?('docs/create_profile') ? 'active' : '' %>">
|
27
|
+
<a href="/docs/api/v1/create_profile">
|
28
|
+
<i class="fa-globe visible-xs"></i>
|
29
|
+
<span class="hidden-xs">Create Profile</span>
|
30
|
+
</a>
|
31
|
+
</li>
|
32
|
+
<li class="<%= nav_active?('docs/update_profile') ? 'active' : '' %>">
|
33
|
+
<a href="/docs/api/v1/update_profile">
|
34
|
+
<i class="fa-globe visible-xs"></i>
|
35
|
+
<span class="hidden-xs">Update Profile</span>
|
36
|
+
</a>
|
37
|
+
</li>
|
38
|
+
</ul>
|
39
|
+
|
40
|
+
<style type="text/css">
|
41
|
+
.panel-positive h4.panel-title a { color: #68b828 !important; }
|
42
|
+
.panel-negative h4.panel-title a { color: #cc3f44 !important; }
|
43
|
+
</style>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Negative Case - 1 - should set proper errors if no input is given"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{}
|
7
|
+
eos
|
8
|
+
|
9
|
+
api_output = <<-eos
|
10
|
+
{
|
11
|
+
"success": false,
|
12
|
+
"errors": {
|
13
|
+
"heading": "Registring new mobile number FAILED",
|
14
|
+
"message": "Check if all mandatory details are passed. Refer the error details for technical information",
|
15
|
+
"details": {
|
16
|
+
"country": [
|
17
|
+
"must exist"
|
18
|
+
],
|
19
|
+
"dialing_prefix": [
|
20
|
+
"can't be blank",
|
21
|
+
"is too short (minimum is 2 characters)"
|
22
|
+
],
|
23
|
+
"mobile_number": [
|
24
|
+
"can't be blank",
|
25
|
+
"is too short (minimum is 9 characters)"
|
26
|
+
],
|
27
|
+
"uuid": [
|
28
|
+
"can't be blank"
|
29
|
+
],
|
30
|
+
"device_token": [
|
31
|
+
"can't be blank"
|
32
|
+
]
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
eos
|
37
|
+
|
38
|
+
%>
|
39
|
+
|
40
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
41
|
+
negative_case: true,
|
42
|
+
example_id: "neg_case_1",
|
43
|
+
api_title: api_title,
|
44
|
+
api_input: api_input,
|
45
|
+
api_output: api_output
|
46
|
+
} %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Negative Case - 2 - should set proper errors when device information is missing"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{
|
7
|
+
"country_id": "1",
|
8
|
+
"dialing_prefix": "+92",
|
9
|
+
"mobile_number": "501370323"
|
10
|
+
}
|
11
|
+
eos
|
12
|
+
|
13
|
+
api_output = <<-eos
|
14
|
+
{
|
15
|
+
"success": false,
|
16
|
+
"errors": {
|
17
|
+
"heading": "Registring new mobile number FAILED",
|
18
|
+
"message": "Check if all mandatory details are passed. Refer the error details for technical information",
|
19
|
+
"details": {
|
20
|
+
"uuid": [
|
21
|
+
"can't be blank"
|
22
|
+
],
|
23
|
+
"device_token": [
|
24
|
+
"can't be blank"
|
25
|
+
]
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
eos
|
30
|
+
|
31
|
+
%>
|
32
|
+
|
33
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
34
|
+
negative_case: true,
|
35
|
+
example_id: "neg_case_2",
|
36
|
+
api_title: api_title,
|
37
|
+
api_input: api_input,
|
38
|
+
api_output: api_output
|
39
|
+
} %>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Negative Case - 3 - should set proper errors when registration information is missing"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{
|
7
|
+
"uuid": "jh01u2g01h301h21h23",
|
8
|
+
"device_token": "0182y3b28107b31",
|
9
|
+
"device_name": "Apple iPhone",
|
10
|
+
"device_type": "iPhone 7 Plus",
|
11
|
+
"operating_system": "iOS",
|
12
|
+
"software_version": "iOS 11.2.2"
|
13
|
+
}
|
14
|
+
eos
|
15
|
+
|
16
|
+
api_output = <<-eos
|
17
|
+
{
|
18
|
+
"success": false,
|
19
|
+
"errors": {
|
20
|
+
"heading": "Registring new mobile number FAILED",
|
21
|
+
"message": "Check if all mandatory details are passed. Refer the error details for technical information",
|
22
|
+
"details": {
|
23
|
+
"country": [
|
24
|
+
"must exist"
|
25
|
+
],
|
26
|
+
"dialing_prefix": [
|
27
|
+
"can't be blank",
|
28
|
+
"is too short (minimum is 2 characters)"
|
29
|
+
],
|
30
|
+
"mobile_number": [
|
31
|
+
"can't be blank",
|
32
|
+
"is too short (minimum is 9 characters)"
|
33
|
+
]
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
eos
|
38
|
+
|
39
|
+
%>
|
40
|
+
|
41
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
42
|
+
negative_case: true,
|
43
|
+
example_id: "neg_case_3",
|
44
|
+
api_title: api_title,
|
45
|
+
api_input: api_input,
|
46
|
+
api_output: api_output
|
47
|
+
} %>
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Positive Case - 1 - should register and add a new device"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{
|
7
|
+
"country_id": "1",
|
8
|
+
"city_id": "2",
|
9
|
+
"dialing_prefix": "+91",
|
10
|
+
"mobile_number": "501370321",
|
11
|
+
"uuid": "jh01u2g01h301h21h232",
|
12
|
+
"device_token": "0182y3b28107b31",
|
13
|
+
"device_name": "Apple iPhone",
|
14
|
+
"device_type": "iPhone 7 Plus",
|
15
|
+
"operating_system": "iOS",
|
16
|
+
"software_version": "iOS 11.2.2"
|
17
|
+
}
|
18
|
+
eos
|
19
|
+
|
20
|
+
api_output = <<-eos
|
21
|
+
{
|
22
|
+
"success": true,
|
23
|
+
"alert": {
|
24
|
+
"heading": "An OTP has been sent to you",
|
25
|
+
"message": "Check your mobile for new message from us."
|
26
|
+
},
|
27
|
+
"data": {
|
28
|
+
"registration": {
|
29
|
+
"id": 5,
|
30
|
+
"user_id": null,
|
31
|
+
"country_id": 1,
|
32
|
+
"city_id": null,
|
33
|
+
"dialing_prefix": "+91",
|
34
|
+
"mobile_number": "501370321"
|
35
|
+
},
|
36
|
+
"device": {
|
37
|
+
"id": 6,
|
38
|
+
"user_id": null,
|
39
|
+
"registration_id": 5,
|
40
|
+
"uuid": "jh01u2g01h301h21h232",
|
41
|
+
"device_token": "0182y3b28107b31",
|
42
|
+
"device_name": "Apple iPhone",
|
43
|
+
"device_type": "iPhone 7 Plus",
|
44
|
+
"operating_system": "iOS",
|
45
|
+
"software_version": "iOS 11.2.2",
|
46
|
+
"otp_verified_at": null
|
47
|
+
}
|
48
|
+
},
|
49
|
+
"errors": {
|
50
|
+
"heading": null,
|
51
|
+
"message": null,
|
52
|
+
"details": {}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
eos
|
56
|
+
|
57
|
+
%>
|
58
|
+
|
59
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
60
|
+
negative_case: false,
|
61
|
+
example_id: "pos_case_1",
|
62
|
+
api_title: api_title,
|
63
|
+
api_input: api_input,
|
64
|
+
api_output: api_output
|
65
|
+
} %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Negative Case - 1 - should set proper errors if no input is given"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{}
|
7
|
+
eos
|
8
|
+
|
9
|
+
api_output = <<-eos
|
10
|
+
{
|
11
|
+
"success": false,
|
12
|
+
"errors": {
|
13
|
+
"heading": "Unexpected Failure",
|
14
|
+
"message": "We're sorry, but something went wrong (500)",
|
15
|
+
"details": {
|
16
|
+
"uuid": "is invalid"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
eos
|
21
|
+
|
22
|
+
%>
|
23
|
+
|
24
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
25
|
+
negative_case: true,
|
26
|
+
example_id: "neg_case_1",
|
27
|
+
api_title: api_title,
|
28
|
+
api_input: api_input,
|
29
|
+
api_output: api_output
|
30
|
+
} %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Positive Case - 1 - should resend the otp for valid inputs"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{
|
7
|
+
"uuid": "asd907asdba78sbda",
|
8
|
+
"mobile_number": "292991230",
|
9
|
+
"dialing_prefix": "+91"
|
10
|
+
}
|
11
|
+
eos
|
12
|
+
|
13
|
+
api_output = <<-eos
|
14
|
+
{
|
15
|
+
"success": true,
|
16
|
+
"alert": {
|
17
|
+
"heading": "An new OTP has been sent to you",
|
18
|
+
"message": "Check your mobile for new message from us."
|
19
|
+
}
|
20
|
+
}
|
21
|
+
eos
|
22
|
+
|
23
|
+
%>
|
24
|
+
|
25
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
26
|
+
negative_case: false,
|
27
|
+
example_id: "pos_case_1",
|
28
|
+
api_title: api_title,
|
29
|
+
api_input: api_input,
|
30
|
+
api_output: api_output
|
31
|
+
} %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
api_title = "Negative Case - 1 - should set proper errors if no input is given"
|
4
|
+
|
5
|
+
api_input = <<-eos
|
6
|
+
{
|
7
|
+
"uuid": "asd907asdba78sbda",
|
8
|
+
"mobile_number": "292991230",
|
9
|
+
"dialing_prefix": "+91"
|
10
|
+
}
|
11
|
+
eos
|
12
|
+
|
13
|
+
api_output = <<-eos
|
14
|
+
{
|
15
|
+
"success": false,
|
16
|
+
"errors": {
|
17
|
+
"heading": "OTP verification was failed",
|
18
|
+
"message": "Make sure that you enter the OTP correctly.",
|
19
|
+
"details": {
|
20
|
+
"otp": "doesn't match with our database"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
eos
|
25
|
+
|
26
|
+
%>
|
27
|
+
|
28
|
+
<%= render partial: "kuppayam/api/docs/example", locals: {
|
29
|
+
negative_case: true,
|
30
|
+
example_id: "neg_case_1",
|
31
|
+
api_title: api_title,
|
32
|
+
api_input: api_input,
|
33
|
+
api_output: api_output
|
34
|
+
} %>
|