devise-ios-rails 1.0.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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +114 -0
  3. data/Rakefile +3 -0
  4. data/app/controllers/devise_ios_rails/passwords_controller.rb +29 -0
  5. data/app/controllers/devise_ios_rails/registrations_controller.rb +19 -0
  6. data/app/serializers/errors_serializer.rb +16 -0
  7. data/app/services/devise_ios_rails/change_password_service.rb +26 -0
  8. data/lib/devise-ios-rails.rb +54 -0
  9. data/lib/devise-ios-rails/engine.rb +5 -0
  10. data/lib/devise-ios-rails/rails/routes.rb +19 -0
  11. data/lib/devise-ios-rails/version.rb +3 -0
  12. data/lib/tasks/devise-ios-rails_tasks.rake +4 -0
  13. data/spec/devise-ios-rails_test.rb +7 -0
  14. data/spec/dummy/Gemfile +75 -0
  15. data/spec/dummy/Gemfile.lock +537 -0
  16. data/spec/dummy/README.md +225 -0
  17. data/spec/dummy/Rakefile +6 -0
  18. data/spec/dummy/app/assets/javascripts/active_admin.js.coffee +1 -0
  19. data/spec/dummy/app/assets/javascripts/application.js.coffee +0 -0
  20. data/spec/dummy/app/assets/javascripts/secret_spaces.coffee +3 -0
  21. data/spec/dummy/app/assets/stylesheets/active_admin.css.scss +17 -0
  22. data/spec/dummy/app/assets/stylesheets/application.css.scss +0 -0
  23. data/spec/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -0
  24. data/spec/dummy/app/assets/stylesheets/secret_spaces.css.scss +3 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  26. data/spec/dummy/app/controllers/secret_spaces_controller.rb +49 -0
  27. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  28. data/spec/dummy/app/helpers/secret_spaces_helper.rb +2 -0
  29. data/spec/dummy/app/models/secret_space.rb +3 -0
  30. data/spec/dummy/app/models/user.rb +5 -0
  31. data/spec/dummy/app/serializers/secret_space_serializer.rb +3 -0
  32. data/spec/dummy/app/serializers/user_serializer.rb +8 -0
  33. data/spec/dummy/app/serializers/v1/base_serializer.rb +5 -0
  34. data/spec/dummy/app/serializers/v1/user_serializer.rb +4 -0
  35. data/spec/dummy/app/views/secret_spaces/_form.html.haml +13 -0
  36. data/spec/dummy/app/views/secret_spaces/edit.html.haml +7 -0
  37. data/spec/dummy/app/views/secret_spaces/index.html.haml +19 -0
  38. data/spec/dummy/app/views/secret_spaces/new.html.haml +5 -0
  39. data/spec/dummy/app/views/secret_spaces/show.html.haml +9 -0
  40. data/spec/dummy/bin/bundle +3 -0
  41. data/spec/dummy/bin/bundler +16 -0
  42. data/spec/dummy/bin/rails +8 -0
  43. data/spec/dummy/bin/rake +8 -0
  44. data/spec/dummy/bin/rspec +20 -0
  45. data/spec/dummy/bin/spring +18 -0
  46. data/spec/dummy/config.ru +12 -0
  47. data/spec/dummy/config/application.rb +23 -0
  48. data/spec/dummy/config/boot.rb +8 -0
  49. data/spec/dummy/config/database.yml +20 -0
  50. data/spec/dummy/config/deploy.rb +48 -0
  51. data/spec/dummy/config/deploy/production.rb +5 -0
  52. data/spec/dummy/config/deploy/staging.rb +4 -0
  53. data/spec/dummy/config/environment.rb +5 -0
  54. data/spec/dummy/config/environments/development.rb +19 -0
  55. data/spec/dummy/config/environments/heroku.rb +26 -0
  56. data/spec/dummy/config/environments/production.rb +26 -0
  57. data/spec/dummy/config/environments/staging.rb +27 -0
  58. data/spec/dummy/config/environments/test.rb +14 -0
  59. data/spec/dummy/config/initializers/active_model_serializer.rb +5 -0
  60. data/spec/dummy/config/initializers/assets.rb +8 -0
  61. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  62. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  63. data/spec/dummy/config/initializers/devise.rb +47 -0
  64. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  65. data/spec/dummy/config/initializers/inflections.rb +16 -0
  66. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  67. data/spec/dummy/config/initializers/session_store.rb +3 -0
  68. data/spec/dummy/config/initializers/simple_token_authentication.rb +25 -0
  69. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  70. data/spec/dummy/config/locales/devise.en.yml +60 -0
  71. data/spec/dummy/config/locales/en.yml +23 -0
  72. data/spec/dummy/config/routes.rb +10 -0
  73. data/spec/dummy/config/secrets.yml +17 -0
  74. data/spec/dummy/db/migrate/20141127081722_devise_create_users.rb +19 -0
  75. data/spec/dummy/db/migrate/20141127114158_add_authentication_token_to_users.rb +6 -0
  76. data/spec/dummy/db/migrate/20141201085308_add_unique_index_to_authentication_token_in_users.rb +6 -0
  77. data/spec/dummy/db/migrate/20141201111915_remove_username_from_users.rb +5 -0
  78. data/spec/dummy/db/migrate/20141208080520_create_secret_spaces.rb +9 -0
  79. data/spec/dummy/db/migrate/20141215153026_create_active_admin_comments.rb +19 -0
  80. data/spec/dummy/db/saaskit_development.sqlite3 +0 -0
  81. data/spec/dummy/db/saaskit_test.sqlite3 +0 -0
  82. data/spec/dummy/db/schema.rb +51 -0
  83. data/spec/dummy/db/seeds.rb +1 -0
  84. data/spec/dummy/log/development.log +610 -0
  85. data/spec/dummy/log/test.log +10113 -0
  86. data/spec/dummy/spec/api/v1/authorized_users_spec.rb +141 -0
  87. data/spec/dummy/spec/api/v1/login_spec.rb +82 -0
  88. data/spec/dummy/spec/api/v1/request_password_reset_spec.rb +39 -0
  89. data/spec/dummy/spec/api/v1/unauthorized_users_spec.rb +69 -0
  90. data/spec/dummy/spec/factories/authentications.rb +48 -0
  91. data/spec/dummy/spec/factories/secret_spaces.rb +6 -0
  92. data/spec/dummy/spec/factories/users.rb +13 -0
  93. data/spec/dummy/spec/factories_spec.rb +21 -0
  94. data/spec/dummy/spec/rails_helper.rb +16 -0
  95. data/spec/dummy/spec/serializers/v1/user_serializer_spec.rb +12 -0
  96. data/spec/dummy/spec/services/devise_ios_rails/change_password_service_spec.rb +47 -0
  97. data/spec/dummy/spec/spec_helper.rb +24 -0
  98. data/spec/dummy/spec/support/devise.rb +3 -0
  99. data/spec/dummy/spec/support/factory_girl.rb +7 -0
  100. data/spec/dummy/spec/support/helpers/json.rb +3 -0
  101. data/spec/dummy/spec/support/shared_contexts/authenticated.rb +3 -0
  102. data/spec/dummy/spec/support/shared_contexts/json_format.rb +5 -0
  103. data/spec/dummy/spec/support/shared_examples/authorized.rb +18 -0
  104. data/spec/dummy/spec/support/shared_examples/requests.rb +65 -0
  105. data/spec/rails_helper.rb +52 -0
  106. data/spec/serializers/errors_serializer_spec.rb +11 -0
  107. data/spec/spec_helper.rb +85 -0
  108. metadata +336 -0
@@ -0,0 +1,141 @@
1
+ require 'rails_helper'
2
+ describe 'authorized users endpoint' do
3
+ include Rack::Test::Methods
4
+ include_context 'format: json'
5
+
6
+ describe "Update User" do
7
+ include_context 'authenticated'
8
+
9
+ let(:url) { "v1/users" }
10
+ let(:user) { create(:user) }
11
+ let(:params) { { user: attributes_for(:user, email: 'changed@example.com') } }
12
+
13
+ subject { put url, params }
14
+
15
+ it_behaves_like "needs authorization"
16
+
17
+ context "with valid token" do
18
+ it_behaves_like "a successful JSON PUT request"
19
+
20
+ it "doesn't create a new record" do
21
+ expect{ subject }.not_to change(User, :count)
22
+ end
23
+
24
+ it "returns a user" do
25
+ json_response = json_for(subject)
26
+ expect(json_response).to have_key('user')
27
+ end
28
+
29
+ it "serializes user with user serializer" do
30
+ json_response = json_for(subject)
31
+ expected_keys = UserSerializer.new(user).serializable_object.keys.map(&:to_s)
32
+ expect(json_response['user'].keys).to eq expected_keys
33
+ end
34
+ end
35
+
36
+ context "with invalid params" do
37
+ let(:params) { { user: attributes_for(:user, email: 'not_valid_email') } }
38
+
39
+ it_behaves_like "a bad JSON request", 422
40
+
41
+ it "returns error object" do
42
+ error = {
43
+ message: 'Validation failed: Email is invalid',
44
+ code: 0,
45
+ status: 422
46
+ }.stringify_keys
47
+ json_response = json_for(subject)
48
+
49
+ expect(json_response).to eq('error' => error)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "Delete Own Account" do
55
+ include_context 'authenticated'
56
+
57
+ let(:url) { "v1/users" }
58
+ let(:user) { create(:user) }
59
+ let(:params) { {} }
60
+
61
+ subject { delete url, params }
62
+
63
+ it_behaves_like "needs authorization"
64
+
65
+ context "with valid token" do
66
+ it_behaves_like "a successful JSON DELETE request"
67
+
68
+ it "removes a user" do
69
+ expect{ subject }.to change(User, :count).by(-1)
70
+ end
71
+
72
+ it "returns a user" do
73
+ json_response = json_for(subject)
74
+ expect(json_response).to have_key('user')
75
+ end
76
+
77
+ it "serializes user with user serializer" do
78
+ expect(subject.body).to eq UserSerializer.new(user).to_json
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "Change User password" do
84
+ include_context 'authenticated'
85
+
86
+ let(:url) { "v1/users/password" }
87
+ let(:user) { create(:user) }
88
+ let(:params) do
89
+ {
90
+ user: {
91
+ password: 'new_pass',
92
+ passwordConfirmation: 'new_pass',
93
+ }
94
+ }
95
+ end
96
+
97
+ subject { put url, params }
98
+
99
+ context "with valid token" do
100
+ it_behaves_like "a successful JSON PUT request"
101
+
102
+ it "doesn't create a new record" do
103
+ expect{ subject }.not_to change(User, :count)
104
+ end
105
+
106
+ it "returns a user" do
107
+ json_response = json_for(subject)
108
+ expect(json_response).to have_key('user')
109
+ end
110
+
111
+ it "changes user password" do
112
+ expect{ json_for(subject)['user']['password'] }
113
+ .to change{ user.reload.encrypted_password }
114
+ end
115
+ end
116
+
117
+ context "with invalid params" do
118
+ let(:params) do
119
+ {
120
+ user: {
121
+ password: 'new_pass',
122
+ passwordConfirmation: 'not_match',
123
+ }
124
+ }
125
+ end
126
+
127
+ it_behaves_like "a bad JSON request", 422
128
+
129
+ it "returns error object" do
130
+ error = {
131
+ message: "Validation failed: Password confirmation doesn't match Password",
132
+ code: 0,
133
+ status: 422
134
+ }.stringify_keys
135
+ json_response = json_for(subject)
136
+
137
+ expect(json_response).to eq('error' => error)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,82 @@
1
+ describe 'login to application endpoint' do
2
+ include Rack::Test::Methods
3
+ include_context 'format: json'
4
+
5
+ describe "login a user" do
6
+ let(:url) { 'v1/users/sign_in' }
7
+ let(:user) { create(:user) }
8
+ subject { post url, params }
9
+
10
+ context "with valid params" do
11
+ let(:params) do
12
+ {
13
+ user: {
14
+ email: user.email,
15
+ password: user.password,
16
+ }
17
+ }
18
+ end
19
+
20
+ it_behaves_like "a successful JSON POST request"
21
+ end
22
+
23
+ context "with invalid params" do
24
+ invalid_params = [
25
+ {},
26
+ { user: { email: 'ios_man@example.com' } },
27
+ { user: { password: 'alcatraz' } },
28
+ ]
29
+ invalid_params.each do |invalid_param|
30
+ it_behaves_like "an unauthorized JSON request" do
31
+ let(:params) { invalid_param }
32
+ end
33
+ end
34
+ end
35
+
36
+ context "with a valid user" do
37
+ let(:params) do
38
+ {
39
+ user: {
40
+ email: user.email,
41
+ password: user.password,
42
+ }
43
+ }
44
+ end
45
+
46
+ it "returns a user" do
47
+ json_response = json_for(subject)
48
+ expect(json_response).to have_key('user')
49
+ end
50
+
51
+ it "serializes user with user serializer" do
52
+ expect(subject.body).to eq UserSerializer.new(user).to_json
53
+ end
54
+ end
55
+
56
+ context "there is no such user in DB" do
57
+ let(:params) do
58
+ {
59
+ user: {
60
+ email: 'non_existent',
61
+ password: 'fictional',
62
+ }
63
+ }
64
+ end
65
+
66
+ it_behaves_like "an unauthorized JSON request"
67
+ end
68
+
69
+ context "password doesn't match the user" do
70
+ let(:params) do
71
+ {
72
+ user: {
73
+ email: user.email,
74
+ password: 'fictional',
75
+ }
76
+ }
77
+ end
78
+
79
+ it_behaves_like "an unauthorized JSON request"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,39 @@
1
+ shared_examples "a successful request_password_request" do
2
+ it_behaves_like "a successful JSON POST request"
3
+
4
+ it "returns empty json body" do
5
+ expect(subject.body).to eq '{}'
6
+ end
7
+ end
8
+
9
+ describe 'reset your password endpoint' do
10
+ include Rack::Test::Methods
11
+ include_context 'format: json'
12
+
13
+ describe "request a password reset" do
14
+ let(:url) { 'v1/users/password' }
15
+ let(:user) { create(:user) }
16
+
17
+ subject { post url, params }
18
+
19
+ context "with valid params" do
20
+ let(:params) { { user: { email: user.email } } }
21
+
22
+ it_behaves_like "a successful request_password_request"
23
+
24
+ it "sends reset instructions to a user" do
25
+ expect{ subject }.to change(ActionMailer::Base.deliveries, :count).by(1)
26
+ end
27
+ end
28
+
29
+ context "there is no such user" do
30
+ let(:params) { { user: { email: 'non_existent' } } }
31
+
32
+ it_behaves_like "a successful request_password_request"
33
+
34
+ it "doesn't send any email" do
35
+ expect{ subject }.to change(ActionMailer::Base.deliveries, :count).by(0)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,69 @@
1
+ describe 'endpoints for unauthorized users' do
2
+ include Rack::Test::Methods
3
+ include_context 'format: json'
4
+
5
+ describe "register a user" do
6
+ let(:url) { 'v1/users' }
7
+ let(:user) { build(:user) }
8
+
9
+ subject { post url, params }
10
+
11
+ context "with valid params" do
12
+ let(:params) do
13
+ {
14
+ user: {
15
+ email: user.email,
16
+ password: user.password,
17
+ }
18
+ }
19
+ end
20
+
21
+ it_behaves_like "a successful JSON POST request"
22
+
23
+ it 'creates a new user' do
24
+ expect{ subject }.to change(User, :count).by(1)
25
+ end
26
+
27
+ it "returns a user" do
28
+ json_response = json_for(subject)
29
+ expect(json_response).to have_key('user')
30
+ end
31
+
32
+ it "serializes user with user serializer" do
33
+ json = subject.body
34
+ user = User.find_by_email(params[:user][:email])
35
+ expect(json).to eq UserSerializer.new(user).to_json
36
+ end
37
+ end
38
+
39
+ context "with invalid params" do
40
+ invalid_params = [
41
+ { },
42
+ { user: { email: 'ios_man@example.com' } },
43
+ { user: { password: 'alcatraz' } },
44
+ ]
45
+ invalid_params.each do |invalid_param|
46
+ it_behaves_like "a bad JSON request", 422 do
47
+ let(:params) { invalid_param }
48
+ end
49
+ end
50
+ end
51
+
52
+ context "with invalid email" do
53
+ let(:params) { { user: { email: 'invalid_email', password: 'alcatraz' } } }
54
+
55
+ it_behaves_like "a bad JSON request", 422
56
+
57
+ it 'returns error object' do
58
+ error = {
59
+ message: 'Validation failed: Email is invalid',
60
+ code: 0,
61
+ status: 422
62
+ }.stringify_keys
63
+ json_response = json_for(subject)
64
+
65
+ expect(json_response).to eq('error' => error)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,48 @@
1
+ class AuthenticationFactory
2
+ attr_reader :user_token, :user_email
3
+
4
+ def initialize(user_token:, user_email:)
5
+ @user_token = user_token
6
+ @user_email = user_email
7
+ end
8
+
9
+ def to_hash
10
+ {
11
+ userToken: user_token,
12
+ userEmail: user_email,
13
+ }
14
+ end
15
+
16
+ def set_headers(session)
17
+ session.header('X-User-Token', @user_token)
18
+ session.header('X-User-Email', @user_email)
19
+ end
20
+ end
21
+
22
+ FactoryGirl.define do
23
+ factory :authentication, class: AuthenticationFactory do
24
+ skip_create
25
+
26
+ transient do
27
+ user
28
+ end
29
+
30
+ initialize_with do
31
+ user_token ||= user.authentication_token
32
+ user_email ||= user.email
33
+ new(
34
+ user_token: user_token,
35
+ user_email: user_email,
36
+ )
37
+ end
38
+ end
39
+
40
+ factory :invalid_authentication, class: AuthenticationFactory do
41
+ initialize_with do
42
+ new(
43
+ user_token: 'non existent',
44
+ user_email: 'no_such@example.com',
45
+ )
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ factory :secret_space do
3
+ text "MyString"
4
+ end
5
+
6
+ end
@@ -0,0 +1,13 @@
1
+ FactoryGirl.define do
2
+ sequence(:email) { |n| "ios_user-#{n}@example.com" }
3
+ factory :user do
4
+ email
5
+ password 'alcatraz'
6
+
7
+ trait :full do
8
+ reset_password_token { Devise.token_generator.generate(User, :reset_password_token) }
9
+ reset_password_sent_at { Time.now }
10
+ remember_created_at { Time.now }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ FactoryGirl.factories.each do |factory|
2
+ describe "The #{factory.name} factory" do
3
+ it 'is valid' do
4
+ object = build(factory.name)
5
+ if object.methods.include? :valid?
6
+ expect(object).to be_valid
7
+ end
8
+ end
9
+ end
10
+
11
+ factory.defined_traits.each do |trait|
12
+ describe "The #{trait.name} #{factory.name} factory" do
13
+ it 'is valid' do
14
+ object = build(factory.name, trait.name)
15
+ if object.methods.include? :valid?
16
+ expect(object).to be_valid
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV.fetch("RAILS_ENV") { 'test' }
3
+ require 'spec_helper'
4
+ require File.expand_path("../../config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+
7
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
11
+ config.use_transactional_fixtures = false
12
+ config.infer_spec_type_from_file_location!
13
+ config.backtrace_formatter.exclusion_patterns.push(/gems/)
14
+
15
+ Capybara.javascript_driver = :webkit
16
+ end
@@ -0,0 +1,12 @@
1
+ module V1
2
+ describe UserSerializer do
3
+ let(:user) { build(:user, :full) }
4
+ subject { described_class.new(user).attributes }
5
+
6
+ it { expect(subject[:id]).to eq(user.id) }
7
+ it { expect(subject[:email]).to eq(user.email) }
8
+ it { expect(subject[:authentication_token]).to eq(user.authentication_token) }
9
+ it { expect(subject[:created_at]).to eq(user.created_at) }
10
+ it { expect(subject[:updated_at]).to eq(user.updated_at) }
11
+ end
12
+ end