crusade_rails 0.8.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/crusade_rails/abstract_notification.js.coffee +38 -0
  3. data/app/assets/javascripts/crusade_rails/configuration.js.coffee.erb +2 -1
  4. data/app/assets/javascripts/crusade_rails/local_notification.js.coffee +23 -0
  5. data/app/assets/javascripts/crusade_rails/notification_permission.js.coffee +3 -1
  6. data/app/assets/javascripts/crusade_rails/push_notification.coffee +42 -0
  7. data/app/controllers/crusade_rails/apns/v1/push_package_controller.rb +34 -3
  8. data/app/controllers/crusade_rails/apns/v1/subscription_controller.rb +5 -1
  9. data/app/controllers/crusade_rails/application_controller.rb +2 -2
  10. data/app/services/crusade_rails/user_subscription_service.rb +41 -7
  11. data/config/routes.rb +2 -0
  12. data/db/migrate/20130917203302_create_crusade_rails_user_subscriptions.rb +1 -0
  13. data/lib/crusade_rails.rb +1 -0
  14. data/lib/crusade_rails/configuration.rb +45 -0
  15. data/lib/crusade_rails/version.rb +1 -1
  16. data/lib/generators/crusade/install/templates/initializer.rb +3 -3
  17. data/test/controllers/apns/v1/push_package_controller_test.rb +39 -7
  18. data/test/controllers/apns/v1/subscription_controller_test.rb +3 -1
  19. data/test/dummy/config/initializers/crusade.rb +3 -3
  20. data/test/dummy/db/development.sqlite3 +0 -0
  21. data/test/dummy/db/migrate/{20130922190000_create_crusade_rails_user_subscriptions.crusade_rails.rb → 20130925062705_create_crusade_rails_user_subscriptions.crusade_rails.rb} +1 -0
  22. data/test/dummy/db/schema.rb +2 -1
  23. data/test/dummy/db/test.sqlite3 +0 -0
  24. data/test/dummy/log/development.log +7 -470
  25. data/test/dummy/log/test.log +36862 -3832
  26. data/test/integration/configuration_test.rb +29 -0
  27. data/test/integration/push_package_integration_test.rb +9 -2
  28. data/test/javascripts/support/configuration.js.coffee +4 -4
  29. data/test/javascripts/support/disable_logger.coffee +1 -0
  30. data/test/javascripts/support/fake_notification.js.coffee +4 -0
  31. data/test/javascripts/support/jquery.mockajax.js +587 -0
  32. data/test/javascripts/support/safari.js.coffee +6 -1
  33. data/test/javascripts/unit/configuration_test.js.coffee +5 -4
  34. data/test/javascripts/unit/local_notification_test.js.coffee +130 -0
  35. data/test/javascripts/unit/notification_permission_test.js.coffee +5 -5
  36. data/test/javascripts/unit/push_notification_test.js.coffee +180 -0
  37. data/test/routes/apns_routes_test.rb +6 -0
  38. data/test/services/user_subscription_service_test.rb +126 -19
  39. metadata +22 -93
  40. data/app/assets/javascripts/crusade_rails/crusade.js.coffee +0 -46
  41. data/test/dummy/tmp/cache/assets/development/sprockets/07be86ef00416c18f2f7dd96f4603129 +0 -0
  42. data/test/dummy/tmp/cache/assets/development/sprockets/116d0ea1f1fccbc5f17329e738b48f32 +0 -0
  43. data/test/dummy/tmp/cache/assets/development/sprockets/1c6cab9972997baaf0f7fd1599e62590 +0 -0
  44. data/test/dummy/tmp/cache/assets/development/sprockets/2a4f82e222d708931c0b88831e1bb864 +0 -0
  45. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  46. data/test/dummy/tmp/cache/assets/development/sprockets/2fe1114a6234d617f0bb5e464a840942 +0 -0
  47. data/test/dummy/tmp/cache/assets/development/sprockets/39b9141911bd7b575b7e782b8c405a0d +0 -0
  48. data/test/dummy/tmp/cache/assets/development/sprockets/3c9d7a4a4511e1418a3f5e9beaac8d0a +0 -0
  49. data/test/dummy/tmp/cache/assets/development/sprockets/45a685d3bc33555e456c32424fd838e8 +0 -0
  50. data/test/dummy/tmp/cache/assets/development/sprockets/576608e546507cd114398639d7f7bd5d +0 -0
  51. data/test/dummy/tmp/cache/assets/development/sprockets/57adfe7d0eeb4aca9491ffb75157956e +0 -0
  52. data/test/dummy/tmp/cache/assets/development/sprockets/5c7b888c11190fa68628e8fd3212e8fd +0 -0
  53. data/test/dummy/tmp/cache/assets/development/sprockets/5ded1a08ed08028fbe21471a88881d28 +0 -0
  54. data/test/dummy/tmp/cache/assets/development/sprockets/5e40cea3d1e28179f2a2ad998d1f26f7 +0 -0
  55. data/test/dummy/tmp/cache/assets/development/sprockets/618327f5ca738fb1d560cdf13c073bf3 +0 -0
  56. data/test/dummy/tmp/cache/assets/development/sprockets/6e6652fce2d9f8b871274ccb2af329c7 +0 -0
  57. data/test/dummy/tmp/cache/assets/development/sprockets/6f5e75e28ef2f140b52beb6f1b6609b9 +0 -0
  58. data/test/dummy/tmp/cache/assets/development/sprockets/7161340e0502d24611730dd49b15e115 +0 -0
  59. data/test/dummy/tmp/cache/assets/development/sprockets/7d4e507c01e7ef7a4dc9d7f9c5478ca4 +0 -0
  60. data/test/dummy/tmp/cache/assets/development/sprockets/803bc12cb782253e6b4191a7346991c5 +0 -0
  61. data/test/dummy/tmp/cache/assets/development/sprockets/8b3d3f72f349b54596b95558be73d55d +0 -0
  62. data/test/dummy/tmp/cache/assets/development/sprockets/97ba61a3e4a7ec32873e08c29a7a6f94 +0 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/9ccfcc3c008514fb5c35aa7b3d7bbc78 +0 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/a82b6a43a4be516353a2ac1d89f6b610 +0 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/a92311b92483c1f9472df2622e658768 +0 -0
  66. data/test/dummy/tmp/cache/assets/development/sprockets/aba15ac42f92b66ff70b0a3e26184263 +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/b75702adcae93ffe045a33824fc40f12 +0 -0
  68. data/test/dummy/tmp/cache/assets/development/sprockets/be89d70eb8f19e72ed6ad9481a7c1b9a +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/c1d4b2d589a2dc7649e075ffea2d2566 +0 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/cd0a1473787729a36454fd789dd86195 +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/d03fd0d3629c94a744a70d063d15eb6f +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/d572f7956c1b132aba30f71dfb1334d9 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/dc8639471867248d3cfc41c6dad35a43 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/e113ed0ed8564e75067a161599ed7fc9 +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/e2bd66166c81c25a6fea7aab23cf58cf +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/e653b1d89bb66ba5ee551887655e02da +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/eb5bc1e85d69a5ec7063b599c7f6acf1 +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/f084f98622288fc6a4d8fdbc755bcb48 +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/f99eb680da1b65060a9388e0b41f19b0 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/fa3e415ce51e582faa842454baced5a3 +0 -0
  83. data/test/javascripts/unit/crusade_spec.js.coffee +0 -102
@@ -4,4 +4,9 @@
4
4
  fakeResult:
5
5
  permission: 'default'
6
6
  permission: (permissionData) -> console.log 'permission'
7
- requestPermission: (url, pushId, userData, callback) -> callback(window.safari.pushNotification.fakeResult)
7
+ requestPermission: (url, pushId, userData, callback) -> callback(window.safari.pushNotification.fakeResult)
8
+
9
+ @mockLocalNotification = ->
10
+ window.Notification =
11
+ permission: 'default'
12
+ requestPermission: (callback) -> callback(window.Notification.fakeResult)
@@ -1,11 +1,12 @@
1
-
2
1
  describe 'configuration', ->
2
+ beforeEach ->
3
+ loadConfiguration()
3
4
 
4
5
  it 'attaches the configuration on the window', ->
5
- expect(window.crusade).toBeDefined()
6
+ expect(Crusade.configuration).toBeDefined()
6
7
 
7
8
  it 'sets the push_id', ->
8
- expect(window.crusade.pushId).toEqual 'web.com.example.push.id'
9
+ expect(Crusade.configuration.pushId).toEqual 'web.com.example.push.id'
9
10
 
10
11
  it 'sets the webservice url', ->
11
- expect(window.crusade.webserviceUrl).toEqual 'https://www.example.com/push'
12
+ expect(Crusade.configuration.webserviceUrl).toEqual 'https://www.example.com/push'
@@ -0,0 +1,130 @@
1
+ describe 'Crusade.LocalNotification', ->
2
+ subject = null
3
+
4
+ beforeEach ->
5
+ subject = new Crusade.LocalNotification()
6
+
7
+ describe 'request local notification permission', ->
8
+ callback = null
9
+ permissionResult = null
10
+
11
+ beforeEach ->
12
+ mockLocalNotification()
13
+
14
+ callback = (permission) -> permissionResult = permission
15
+
16
+ describe 'the user was already requested', ->
17
+ describe 'the user granted the permission', ->
18
+ it 'executes the success function if the user has already granted the permission', ->
19
+ window.Notification.permission = 'granted'
20
+
21
+ subject.requestPermission().granted(callback)
22
+
23
+ expect(permissionResult.permission).toEqual 'granted'
24
+
25
+ it 'wraps the safari permission into a crusade permission', ->
26
+ window.Notification.permission = 'granted'
27
+
28
+ subject.requestPermission().granted(callback)
29
+
30
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
31
+
32
+ it 'executes the error function if the user has already denied the permission', ->
33
+ window.Notification.permission = 'denied'
34
+
35
+ subject.requestPermission().denied(callback)
36
+
37
+ expect(permissionResult.permission).toEqual 'denied'
38
+
39
+ describe 'the user has never been requested', ->
40
+ permissionCallback = null
41
+
42
+ beforeEach ->
43
+ permissionCallback = (permission) -> callback(permission)
44
+ mockLocalNotification()
45
+
46
+ describe 'the user grants the permission', ->
47
+ it 'executes the grants function if the user', ->
48
+ window.Notification.fakeResult = 'granted'
49
+
50
+ subject.requestPermission().granted(callback)
51
+
52
+ expect(permissionResult.permission).toEqual 'granted'
53
+
54
+ it 'wraps the safari permission into a crusade permission', ->
55
+ window.Notification.fakeResult = 'granted'
56
+
57
+ subject.requestPermission().granted(callback)
58
+
59
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
60
+
61
+ describe 'the user denies the permission', ->
62
+ it 'executes the error function', ->
63
+ window.Notification.fakeResult = 'denied'
64
+
65
+ subject.requestPermission().denied(callback)
66
+
67
+ expect(permissionResult.permission).toEqual 'denied'
68
+
69
+ describe 'the browser does not support local notifications', ->
70
+ it 'returns unsupported', ->
71
+ window.Notification = undefined
72
+
73
+ subject.requestPermission().denied(callback)
74
+
75
+ expect(permissionResult.permission).toEqual 'unsupported'
76
+
77
+ describe 'checkPermission', ->
78
+ beforeEach ->
79
+ window.Notification.permission = 'granted'
80
+
81
+ describe 'the browser is supported', ->
82
+
83
+ it 'returns the result of the current permission', ->
84
+ permissionResult = subject.checkPermission()
85
+
86
+ expect(permissionResult.permission).toEqual 'granted'
87
+
88
+ it 'wraps the safari permission into a crusade permission', ->
89
+ permissionResult = subject.checkPermission()
90
+
91
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
92
+
93
+ describe 'the browser does not support local notifications', ->
94
+ it 'returns unsupported', ->
95
+ window.Notification = undefined
96
+
97
+ permissionResult = subject.checkPermission()
98
+
99
+ expect(permissionResult.permission).toEqual 'unsupported'
100
+
101
+ describe 'send notification', ->
102
+ notification = null
103
+
104
+ beforeEach ->
105
+ window.Notification = FakeNotification
106
+
107
+ describe 'the user granted the permission', ->
108
+ beforeEach ->
109
+ window.Notification.permission = 'granted'
110
+
111
+ notification = subject.notify('title', 'the body')
112
+
113
+ it 'creates a new notification', ->
114
+ expect(notification).toBeDefined()
115
+
116
+ it 'sets the title of the notification', ->
117
+ expect(notification.title).toEqual 'title'
118
+
119
+ it 'sets the body of the notification', ->
120
+ expect(notification.body).toEqual 'the body'
121
+
122
+ describe 'the user denied the permission', ->
123
+ beforeEach ->
124
+ window.Notification.permission = 'denied'
125
+
126
+ notification = subject.notify('title', 'the body')
127
+
128
+ it 'returns "unauthorized"', ->
129
+ expect(notification).toEqual 'unauthorized'
130
+
@@ -1,5 +1,5 @@
1
1
 
2
- describe 'NotificationPermission', ->
2
+ describe 'Crusade.NotificationPermission', ->
3
3
  subject = null
4
4
 
5
5
  describe 'constructor', ->
@@ -8,20 +8,20 @@ describe 'NotificationPermission', ->
8
8
  it 'copies the permission', ->
9
9
  safariPermission = { permission: "granted" }
10
10
 
11
- subject = new NotificationPermission(safariPermission)
11
+ subject = new Crusade.NotificationPermission(safariPermission)
12
12
 
13
13
  expect(subject.permission).toEqual "granted"
14
14
 
15
15
  it 'copies the deviceToken', ->
16
16
  safariPermission = { deviceToken: "1234q" }
17
17
 
18
- subject = new NotificationPermission(safariPermission)
18
+ subject = new Crusade.NotificationPermission(safariPermission)
19
19
 
20
20
  expect(subject.deviceToken).toEqual "1234q"
21
21
 
22
22
  describe 'no safariPermission', ->
23
23
  beforeEach ->
24
- subject = new NotificationPermission()
24
+ subject = new Crusade.NotificationPermission()
25
25
 
26
26
  it 'has a default permission', ->
27
27
  expect(subject.permission).toEqual "default"
@@ -31,7 +31,7 @@ describe 'NotificationPermission', ->
31
31
 
32
32
  describe 'isGranted', ->
33
33
  beforeEach ->
34
- subject = new NotificationPermission()
34
+ subject = new Crusade.NotificationPermission()
35
35
 
36
36
  it 'is granted if the permission is "granted"', ->
37
37
  subject.permission = 'granted'
@@ -0,0 +1,180 @@
1
+ describe 'Crusade.PushNotification', ->
2
+ subject = null
3
+
4
+ beforeEach ->
5
+ subject = new Crusade.PushNotification()
6
+
7
+ describe 'request push notification permission', ->
8
+ callback = null
9
+ permissionResult = null
10
+
11
+ beforeEach ->
12
+ mockSafariPushNotification()
13
+
14
+ callback = (permission) -> permissionResult = permission
15
+
16
+ describe 'the user was already requested', ->
17
+ afterEach ->
18
+ expect(window.safari.pushNotification.permission).toHaveBeenCalledWith 'web.com.example.push.id'
19
+
20
+
21
+ describe 'the user granted the permission', ->
22
+ it 'executes the success function if the user has already granted the permission', ->
23
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
24
+
25
+ subject.requestPermission().granted(callback)
26
+
27
+ expect(permissionResult.permission).toEqual 'granted'
28
+
29
+ it 'wraps the safari permission into a crusade permission', ->
30
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
31
+
32
+ subject.requestPermission().granted(callback)
33
+
34
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
35
+
36
+ describe 'the user denied the permission', ->
37
+ it 'executes the error function if the user has already denied the permission', ->
38
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'denied'})
39
+
40
+ subject.requestPermission().denied(callback)
41
+
42
+ expect(permissionResult.permission).toEqual 'denied'
43
+
44
+ describe 'the user has never been requested', ->
45
+ permissionCallback = null
46
+
47
+ beforeEach ->
48
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'default'})
49
+
50
+ $.mockjax(
51
+ url: 'https://www.example.com/push/v1/pushPackages/web.com.example.push.id/new',
52
+ dataType: 'json'
53
+ responseText: {
54
+ "user_subscription": {
55
+ "user_id": 2,
56
+ "authenticity_token": "abcde"
57
+ }
58
+ })
59
+
60
+ permissionCallback = (permission) -> callback(permission)
61
+
62
+ afterEach ->
63
+ $.mockjaxClear()
64
+
65
+ expectSafariRequest = ->
66
+ expect(window.safari.pushNotification.requestPermission).toHaveBeenCalledWith 'https://www.example.com/push',
67
+ 'web.com.example.push.id'
68
+ {user_id: '2', authenticity_token: 'abcde' }
69
+ jasmine.any(Function)
70
+
71
+ describe 'the user grants the permission', ->
72
+ it 'executes the success function', ->
73
+ window.safari.pushNotification.fakeResult = { permission: 'granted', deviceToken: 'deviceToken' }
74
+ spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
75
+
76
+ subject.requestPermission().granted(callback)
77
+
78
+ expect(permissionResult.permission).toEqual 'granted'
79
+ expectSafariRequest()
80
+
81
+ it 'wraps the safari permission into a crusade permission', ->
82
+ window.safari.pushNotification.fakeResult = { permission: 'granted', deviceToken: 'deviceToken' }
83
+ spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
84
+
85
+ subject.requestPermission().granted(callback)
86
+
87
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
88
+
89
+ describe 'the user denies the permission', ->
90
+ it 'executes the error function', ->
91
+ window.safari.pushNotification.fakeResult = { permission: 'denied' }
92
+ spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
93
+
94
+ subject.requestPermission().denied(callback)
95
+
96
+ expect(permissionResult.permission).toEqual 'denied'
97
+ expectSafariRequest()
98
+
99
+
100
+ describe 'there is an error in the authenticity request', ->
101
+ it 'fails if the request fails', ->
102
+ $.mockjaxClear()
103
+ $.mockjax(
104
+ url: 'https://www.example.com/push/v1/pushPackages/web.com.example.push.id/new'
105
+ dataType: 'json'
106
+ status: 404
107
+ )
108
+ spyOn(window.safari.pushNotification, 'requestPermission')
109
+
110
+ subject.requestPermission().denied(callback)
111
+
112
+ expect(permissionResult.permission).toEqual 'unauthenticated'
113
+
114
+ it 'fails if the request does not contain a permission', ->
115
+ $.mockjaxClear()
116
+ $.mockjax(
117
+ url: 'https://www.example.com/push/v1/pushPackages/web.com.example.push.id/new'
118
+ dataType: 'json'
119
+ responseText: {}
120
+ )
121
+ spyOn(window.safari.pushNotification, 'requestPermission')
122
+
123
+ subject.requestPermission().denied(callback)
124
+
125
+ expect(permissionResult.permission).toEqual 'unauthenticated'
126
+
127
+ describe 'the brwoser is not supported', ->
128
+ it 'returns unsupported if the browser is no Safari', ->
129
+ window.safari = undefined
130
+
131
+ subject.requestPermission().denied(callback)
132
+
133
+ expect(permissionResult.permission).toEqual 'unsupported'
134
+
135
+ it 'returns unsupported if Safari does not support push notifications', ->
136
+ window.safari.pushNotification = undefined
137
+
138
+ subject.requestPermission().denied(callback)
139
+
140
+ expect(permissionResult.permission).toEqual 'unsupported'
141
+
142
+ describe 'checkPermission', ->
143
+ beforeEach ->
144
+ window.safari =
145
+ pushNotification:
146
+ permission: -> true
147
+
148
+ describe 'the browser is supported', ->
149
+ afterEach ->
150
+ expect(window.safari.pushNotification.permission).toHaveBeenCalledWith 'web.com.example.push.id'
151
+
152
+
153
+ it 'returns the result of the current permission', ->
154
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
155
+
156
+ permissionResult = subject.checkPermission()
157
+
158
+ expect(permissionResult.permission).toEqual 'granted'
159
+
160
+ it 'wraps the safari permission into a crusade permission', ->
161
+ spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
162
+
163
+ permissionResult = subject.checkPermission()
164
+
165
+ expect(permissionResult).toEqual jasmine.any(Crusade.NotificationPermission)
166
+
167
+ describe 'the browser is not supported', ->
168
+ it 'returns unsupported if the browser is no Safari', ->
169
+ window.safari = undefined
170
+
171
+ permissionResult = subject.checkPermission()
172
+
173
+ expect(permissionResult.permission).toEqual 'unsupported'
174
+
175
+ it 'returns unsupported if Safari does not support push notifications', ->
176
+ window.safari.pushNotification = undefined
177
+
178
+ permissionResult = subject.checkPermission()
179
+
180
+ expect(permissionResult.permission).toEqual 'unsupported'
@@ -7,6 +7,12 @@ describe 'APNS routes Integration Test' do
7
7
  action: 'create'
8
8
  end
9
9
 
10
+ it 'routes the push package new authorization id' do
11
+ assert_regonize_route 'get', '/apns/v1/pushPackages/web.com.example.push.id/new',
12
+ controller: 'crusade_rails/apns/v1/push_package',
13
+ action: 'new'
14
+ end
15
+
10
16
  it 'routes the push notification subscription' do
11
17
  assert_regonize_route 'post', '/apns/v1/devices/1234a/registrations/web.com.example.push.id',
12
18
  controller: 'crusade_rails/apns/v1/subscription',
@@ -4,39 +4,118 @@ describe CrusadeRails::UserSubscriptionService do
4
4
  before { CrusadeRails::UserSubscription.delete_all }
5
5
  after { CrusadeRails::UserSubscription.delete_all }
6
6
 
7
+ subject { CrusadeRails::UserSubscriptionService.new user_id }
8
+
7
9
  let(:user_id) { 123 }
8
10
 
9
- describe 'register' do
10
- subject { CrusadeRails::UserSubscriptionService.new }
11
+ describe 'initialize' do
12
+ it { subject.user_id.must_equal user_id }
11
13
 
12
- let(:registration) { subject.register user_id, user_token }
13
- let(:user_token) { '1234a' }
14
- let(:subscription) { CrusadeRails::UserSubscription.where(user_id: user_id).first }
14
+ it 'does not support user_id nil' do
15
+ -> { CrusadeRails::UserSubscriptionService.new nil }.must_raise TypeError
16
+ end
17
+
18
+ it 'does not support an non numeric user_id' do
19
+ -> { CrusadeRails::UserSubscriptionService.new 'aaa' }.must_raise ArgumentError
20
+ end
21
+ end
15
22
 
16
- before { registration }
23
+ describe 'new_subscription' do
24
+ let(:subscription) { CrusadeRails::UserSubscription.last }
17
25
 
18
- it 'registers the user id' do
26
+ before { subject.new_subscription }
27
+
28
+ it 'creates a new subscription' do
29
+ subscription.wont_be_nil
30
+ end
31
+
32
+ it 'sets the user id' do
19
33
  subscription.user_id.must_equal user_id
20
34
  end
21
35
 
22
- it 'registers the user token' do
23
- subscription.user_token.must_equal user_token
36
+ it 'generates a long authenticity token' do
37
+ subscription.authenticity_token.wont_be_nil
38
+ (subscription.authenticity_token.size >= 100).must_be_true
24
39
  end
25
40
 
26
- it 'creates a subscription entry' do
27
- subscription.wont_be_nil
41
+ it 'generates different token' do
42
+ tokens = 50.times.map do |i|
43
+ CrusadeRails::UserSubscriptionService.new(user_id).new_subscription.authenticity_token
44
+ end
45
+
46
+ tokens.uniq.must_equal tokens
28
47
  end
29
48
 
30
- it 'does no contains a device token' do
31
- subscription.device_token.must_be_nil
49
+ describe 'the user already has a subscription' do
50
+ it 'does not create a new subscription in database' do
51
+ subject.new_subscription
52
+
53
+ CrusadeRails::UserSubscription.where(user_id: user_id).count.must_equal 1
54
+ end
55
+
56
+ it 'replace the authenticity token' do
57
+ authenticity_token = subscription.authenticity_token
58
+
59
+ subject.new_subscription
60
+
61
+ CrusadeRails::UserSubscription.where(user_id: user_id).last.authenticity_token.wont_equal authenticity_token
62
+ end
32
63
  end
64
+ end
33
65
 
34
- it 'is not activated' do
35
- subscription.active?.must_be_false
66
+ describe 'register' do
67
+ let(:authenticity_token) { 'aaaa' }
68
+ let(:registration) { subject.register authenticity_token, user_token }
69
+ let(:user_token) { '1234a' }
70
+
71
+ let(:subscription) { CrusadeRails::UserSubscription.where(user_id: user_id).first }
72
+ let(:initial) { CrusadeRails::UserSubscription.create(user_id: user_id, authenticity_token: initial_authenticity_token) }
73
+ let(:initial_authenticity_token) { 'aaaa' }
74
+
75
+ before do
76
+ initial
36
77
  end
37
78
 
38
- it 'returns true when the registration is successfull' do
39
- registration.must_be_true
79
+ describe 'valid authenticity token' do
80
+ before do
81
+ registration
82
+ end
83
+
84
+ it 'updates the initial subscription' do
85
+ subscription.id.must_equal initial.id
86
+ end
87
+
88
+ it 'registers the user id' do
89
+ subscription.user_id.must_equal user_id
90
+ end
91
+
92
+ it 'registers the user token' do
93
+ subscription.user_token.must_equal user_token
94
+ end
95
+
96
+ it 'creates a subscription entry' do
97
+ subscription.wont_be_nil
98
+ end
99
+
100
+ it 'does no contains a device token' do
101
+ subscription.device_token.must_be_nil
102
+ end
103
+
104
+ it 'is not activated' do
105
+ subscription.active?.must_be_false
106
+ end
107
+
108
+ it 'returns true when the registration is successfull' do
109
+ registration.must_be_true
110
+ end
111
+ end
112
+
113
+ describe 'wrong authenticity token' do
114
+ let(:initial_authenticity_token) { 'bbbbb' }
115
+
116
+ it 'returns unauthenticated' do
117
+ registration.must_equal :unauthenticated
118
+ end
40
119
  end
41
120
  end
42
121
 
@@ -44,7 +123,7 @@ describe CrusadeRails::UserSubscriptionService do
44
123
  let(:user_token) { '1234' }
45
124
  let(:device_token) { 'abcd' }
46
125
 
47
- subject { CrusadeRails::UserSubscriptionService.new}
126
+ subject { CrusadeRails::UserSubscriptionService.new user_id }
48
127
 
49
128
  describe 'no previous subscription' do
50
129
  before do
@@ -77,7 +156,7 @@ describe CrusadeRails::UserSubscriptionService do
77
156
  let(:user_token) { '1234' }
78
157
  let(:device_token) { 'abcd' }
79
158
 
80
- subject { CrusadeRails::UserSubscriptionService.new}
159
+ subject { CrusadeRails::UserSubscriptionService.new user_id }
81
160
 
82
161
  describe 'no previous subscription' do
83
162
  before do
@@ -101,4 +180,32 @@ describe CrusadeRails::UserSubscriptionService do
101
180
  describe 'subscription not found' do
102
181
  end
103
182
  end
183
+
184
+ describe 'authenticate' do
185
+ subject { CrusadeRails::UserSubscriptionService.new(user_id)}
186
+ let(:user_id) { 1234 }
187
+ let(:authenticity_token) { 'abcd' }
188
+
189
+ it 'retuns true if an entry with the same user id & authenticity token exists' do
190
+ CrusadeRails::UserSubscription.create user_id: user_id, authenticity_token: authenticity_token
191
+
192
+ subject.authenticate(authenticity_token).must_be_true
193
+ end
194
+
195
+ it 'retuns false if an entry with the same user id but different authenticity token exists' do
196
+ CrusadeRails::UserSubscription.create user_id: user_id, authenticity_token: "#{authenticity_token}=="
197
+
198
+ subject.authenticate(authenticity_token).must_be_false
199
+ end
200
+
201
+ it 'retuns false if an entry with a different user id and authenticity token exists' do
202
+ CrusadeRails::UserSubscription.create user_id: (user_id + 1), authenticity_token: authenticity_token
203
+
204
+ subject.authenticate(authenticity_token).must_be_false
205
+ end
206
+
207
+ it 'retuns false if there is no entry' do
208
+ subject.authenticate(authenticity_token).must_be_false
209
+ end
210
+ end
104
211
  end