crusade_rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +48 -0
- data/app/assets/javascripts/crusade.js +15 -0
- data/app/assets/javascripts/crusade_rails/configuration.js.coffee.erb +4 -0
- data/app/assets/javascripts/crusade_rails/crusade.js.coffee +46 -0
- data/app/assets/javascripts/crusade_rails/notification_permission.js.coffee +13 -0
- data/app/assets/stylesheets/crusade_rails/application.css +13 -0
- data/app/controllers/crusade_rails/apns/v1/log_controller.rb +13 -0
- data/app/controllers/crusade_rails/apns/v1/push_package_controller.rb +23 -0
- data/app/controllers/crusade_rails/apns/v1/subscription_controller.rb +37 -0
- data/app/controllers/crusade_rails/application_controller.rb +14 -0
- data/app/helpers/crusade_rails/application_helper.rb +4 -0
- data/app/models/crusade_rails/user_subscription.rb +4 -0
- data/app/services/crusade_rails/notification_service.rb +36 -0
- data/app/services/crusade_rails/user_subscription_service.rb +36 -0
- data/app/views/layouts/crusade_rails/application.html.erb +14 -0
- data/config/initializers/teaspoon.rb +65 -0
- data/config/routes.rb +15 -0
- data/db/migrate/20130917203302_create_crusade_rails_user_subscriptions.rb +12 -0
- data/lib/crusade_rails/configuration_loader.rb +33 -0
- data/lib/crusade_rails/engine.rb +9 -0
- data/lib/crusade_rails/version.rb +3 -0
- data/lib/crusade_rails.rb +4 -0
- data/lib/generators/crusade/install/USAGE +9 -0
- data/lib/generators/crusade/install/install_generator.rb +17 -0
- data/lib/generators/crusade/install/templates/configuration.yml +23 -0
- data/lib/generators/crusade/install/templates/initializer.rb +2 -0
- data/lib/tasks/crusade_rails_tasks.rake +4 -0
- data/test/controllers/apns/v1/log_controller_test.rb +35 -0
- data/test/controllers/apns/v1/push_package_controller_test.rb +41 -0
- data/test/controllers/apns/v1/subscription_controller_test.rb +61 -0
- data/test/crusade_rails_test.rb +7 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/certificate.p12 +0 -0
- data/test/dummy/config/crusade.yml +23 -0
- data/test/dummy/config/crusade_absolute.yml +13 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/crusade.rb +2 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20130921092524_create_crusade_rails_user_subscriptions.crusade_rails.rb +13 -0
- data/test/dummy/db/schema.rb +34 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/lib/icon.iconset/icon_128x128.png +0 -0
- data/test/dummy/lib/icon.iconset/icon_128x128@2x.png +0 -0
- data/test/dummy/lib/icon.iconset/icon_16x16.png +0 -0
- data/test/dummy/lib/icon.iconset/icon_16x16@2x.png +0 -0
- data/test/dummy/lib/icon.iconset/icon_32x32.png +0 -0
- data/test/dummy/lib/icon.iconset/icon_32x32@2x.png +0 -0
- data/test/dummy/log/development.log +9000 -0
- data/test/dummy/log/test.log +18388 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/0330051201f83b2ff3843e3c6747e79d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/0534641409a2140bc6e7ebc3ffb3a54d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/108a4cc5d6041a541455f23f064f718f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/10b6d318fbf01394655188cb55968932 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/1903ce46cdbce5cbddb3f58cacb00c89 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/19e13c514bd0c76f667eacd20d91d72c +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/1d295354fabfd91032e5c51cf32fe192 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/24efeb1e9e576159a181fb53b3f114a7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/27cb4afd1625534b2a374a81b9df26de +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/28fcfef8d3cf8654ba549bc1761e83e4 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2969a922d5c2342a65712f8bd9cc99a6 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2de3b3bd851fd121492b6d4ac403e556 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2e0be385ec13186af8c1ea31b03b96fd +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2e465486b1a6c8f2d49a4ed114d70396 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3125a19a8cea48c16b56e8b59a5c5294 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3cc705332293b3c69203db8a96e9d830 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3cd8491f62d0bb72dc92a13205463599 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3cde555d17b62d65401cc9272bae6e08 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/556f3a4cc7bf634157a1bcb26a3d2b6d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5f268780e6c88d505c5593761755010a +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/6701d9e3411fdcd8e5e547bdec87cb66 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/6b77a9aa8954a56d3da421ee8f0813e8 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/6f19bfcf39fc6e2ba42b315015e41741 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/72194bfe82d488c5e022c9046c0581c5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/732aa0a732c68b36c462c1aa61e9c5db +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/742719bcba2beaa6ee593b3c6eabe40b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/753c20567a3407e94309e3a586ba70c1 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/76d2c2ca1f8747e7c285677d59d1f9d9 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8674169919e38981b419dbd475a583aa +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8770d1f7ac46ca50bf453462671ea0b9 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8b4c20d1cbaeadc08407a48823e8c7c3 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/8d66da576394374d14318805fe809466 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/9aacc018015dba444d327301c20b63c5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/9bf8f0dcacf365b365a44fc7acaf5b33 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/9f6a5c70035131b2862f0cf1b1ffba5f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/aa3a6aa3669f27355e35fd070b5ec5cc +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b0f0a9774bdd9aba74bc3dbaa280abd2 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b116102c65d66d0bac493130339e906f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b3c46efa2d626eb47c04b3299485ada2 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b60162f01dfafeaa2fd08552bee0d7b7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ba4082b2576e0439500c1de73f75e722 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/bd98cfe5b883a49d02e51dff15eb2d62 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d0ba95da0d65927f38a86ec70536acfa +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ddcd3a7d9f01da29b22f5bb8894c9e9d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/dfb8f1f4a35d49c4853bb839dd074b03 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/edb1e911142e4ffa330d5f54129ae937 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f3676986bcff0feb06ca29fc36c62054 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f8e371443421803a78fdbe7fb29531b7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f9b223cb5385faca472d99ad42c60776 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/fcd414d106937117c1f77dafcb48d32d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ff6fd5ae68516118b84d0dc0485e4456 +0 -0
- data/test/fixtures/crusade_rails/default_routes.rb +6 -0
- data/test/generators/install_generator_test.rb +66 -0
- data/test/integration/configuration_loader_test.rb +56 -0
- data/test/integration/push_package_integration_test.rb +14 -0
- data/test/javascripts/support/jquery.js +9790 -0
- data/test/javascripts/support/safari.coffee +7 -0
- data/test/javascripts/test_helper.coffee +25 -0
- data/test/javascripts/unit/configuration_test.js.coffee +11 -0
- data/test/javascripts/unit/crusade_test.js.coffee +102 -0
- data/test/javascripts/unit/notification_permission_test.js.coffee +49 -0
- data/test/routes/apns_routes_test.rb +39 -0
- data/test/services/notification_service_test.rb +69 -0
- data/test/services/user_subscription_service_test.rb +104 -0
- data/test/support/fake_push_notification.rb +24 -0
- data/test/teaspoon_env.rb +33 -0
- data/test/test_helper.rb +27 -0
- metadata +468 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
@mockSafariPushNotification = ->
|
2
|
+
window.safari =
|
3
|
+
pushNotification:
|
4
|
+
fakeResult:
|
5
|
+
permission: 'default'
|
6
|
+
permission: (permissionData) -> console.log 'permission'
|
7
|
+
requestPermission: (url, pushId, userData, callback) -> callback(window.safari.pushNotification.fakeResult)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Teaspoon includes some support files, but you can use anything from your own support path too.
|
2
|
+
# require support/jasmine-jquery
|
3
|
+
# require support/sinon
|
4
|
+
# require support/your-support-file
|
5
|
+
#
|
6
|
+
# Deferring execution
|
7
|
+
# If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call Teaspoon.execute()
|
8
|
+
# after everything has been loaded. Simple example of a timeout:
|
9
|
+
#
|
10
|
+
# Teaspoon.defer = true
|
11
|
+
# setTimeout(Teaspoon.execute, 1000)
|
12
|
+
#
|
13
|
+
# Matching files
|
14
|
+
# By default Teaspoon will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your
|
15
|
+
# spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the
|
16
|
+
# configuration in config/initializers/teaspoon.rb
|
17
|
+
#
|
18
|
+
# Manifest
|
19
|
+
# If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in
|
20
|
+
# the configuration and use this file as a manifest.
|
21
|
+
#
|
22
|
+
# For more information: http://github.com/modeset/teaspoon
|
23
|
+
#
|
24
|
+
# You can require javascript files here. A good place to start is by requiring your application.js.
|
25
|
+
#= require application
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
describe 'configuration', ->
|
3
|
+
|
4
|
+
it 'attaches the configuration on the window', ->
|
5
|
+
expect(window.crusade).toBeDefined()
|
6
|
+
|
7
|
+
it 'sets the push_id', ->
|
8
|
+
expect(window.crusade.pushId).toEqual 'web.com.example.push.id'
|
9
|
+
|
10
|
+
it 'sets the webservice url', ->
|
11
|
+
expect(window.crusade.webserviceUrl).toEqual 'https://www.example.com/push'
|
@@ -0,0 +1,102 @@
|
|
1
|
+
|
2
|
+
describe 'Crusade', ->
|
3
|
+
subject = null
|
4
|
+
|
5
|
+
beforeEach ->
|
6
|
+
subject = new Crusade()
|
7
|
+
|
8
|
+
describe 'request push notification permission', ->
|
9
|
+
callback = null
|
10
|
+
permissionResult = null
|
11
|
+
|
12
|
+
beforeEach ->
|
13
|
+
mockSafariPushNotification()
|
14
|
+
|
15
|
+
callback = (permission) -> permissionResult = permission
|
16
|
+
|
17
|
+
describe 'the user was already requested', ->
|
18
|
+
afterEach ->
|
19
|
+
expect(window.safari.pushNotification.permission).toHaveBeenCalledWith 'web.com.example.push.id'
|
20
|
+
|
21
|
+
|
22
|
+
describe 'the user granted the permission', ->
|
23
|
+
it 'executes the success function if the user has already granted the permission', ->
|
24
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
|
25
|
+
|
26
|
+
subject.requestPermission('userId').granted(callback)
|
27
|
+
|
28
|
+
expect(permissionResult.permission).toEqual 'granted'
|
29
|
+
|
30
|
+
it 'wraps the safari permission into a crusade permission', ->
|
31
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
|
32
|
+
|
33
|
+
subject.requestPermission('userId').granted(callback)
|
34
|
+
|
35
|
+
expect(permissionResult).toEqual jasmine.any(NotificationPermission)
|
36
|
+
|
37
|
+
describe 'the user denied the permission', ->
|
38
|
+
it 'executes the error function if the user has already denied the permission', ->
|
39
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'denied'})
|
40
|
+
|
41
|
+
subject.requestPermission('userId').denied(callback)
|
42
|
+
|
43
|
+
expect(permissionResult.permission).toEqual 'denied'
|
44
|
+
|
45
|
+
describe 'the user has never been requested', ->
|
46
|
+
permissionCallback = null
|
47
|
+
|
48
|
+
beforeEach ->
|
49
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'default'})
|
50
|
+
|
51
|
+
permissionCallback = (permission) -> callback(permission)
|
52
|
+
|
53
|
+
afterEach ->
|
54
|
+
expect(window.safari.pushNotification.requestPermission).toHaveBeenCalledWith 'https://www.example.com/push',
|
55
|
+
'web.com.example.push.id'
|
56
|
+
{userId: 'userId'}
|
57
|
+
jasmine.any(Function)
|
58
|
+
|
59
|
+
describe 'the user denies the permission', ->
|
60
|
+
it 'executes the success function if the user has already granted the permission', ->
|
61
|
+
window.safari.pushNotification.fakeResult = { permission: 'granted', deviceToken: 'deviceToken' }
|
62
|
+
spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
|
63
|
+
|
64
|
+
subject.requestPermission('userId').granted(callback)
|
65
|
+
|
66
|
+
expect(permissionResult.permission).toEqual 'granted'
|
67
|
+
|
68
|
+
it 'wraps the safari permission into a crusade permission', ->
|
69
|
+
window.safari.pushNotification.fakeResult = { permission: 'granted', deviceToken: 'deviceToken' }
|
70
|
+
spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
|
71
|
+
|
72
|
+
subject.requestPermission('userId').granted(callback)
|
73
|
+
|
74
|
+
expect(permissionResult).toEqual jasmine.any(NotificationPermission)
|
75
|
+
|
76
|
+
describe 'the user grants the permission', ->
|
77
|
+
it 'executes the error function if the user has already denied the permission', ->
|
78
|
+
window.safari.pushNotification.fakeResult = { permission: 'denied' }
|
79
|
+
spyOn(window.safari.pushNotification, 'requestPermission').andCallThrough()
|
80
|
+
|
81
|
+
subject.requestPermission('userId').denied(callback)
|
82
|
+
|
83
|
+
expect(permissionResult.permission).toEqual 'denied'
|
84
|
+
|
85
|
+
describe 'checkPermission', ->
|
86
|
+
afterEach ->
|
87
|
+
expect(window.safari.pushNotification.permission).toHaveBeenCalledWith 'web.com.example.push.id'
|
88
|
+
|
89
|
+
|
90
|
+
it 'returns the result of the current permission', ->
|
91
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
|
92
|
+
|
93
|
+
permissionResult = subject.checkPermission()
|
94
|
+
|
95
|
+
expect(permissionResult.permission).toEqual 'granted'
|
96
|
+
|
97
|
+
it 'wraps the safari permission into a crusade permission', ->
|
98
|
+
spyOn(window.safari.pushNotification, 'permission').andReturn({permission: 'granted', deviceToken: 'deviceToken'})
|
99
|
+
|
100
|
+
permissionResult = subject.checkPermission()
|
101
|
+
|
102
|
+
expect(permissionResult).toEqual jasmine.any(NotificationPermission)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
describe 'NotificationPermission', ->
|
3
|
+
subject = null
|
4
|
+
|
5
|
+
describe 'constructor', ->
|
6
|
+
safariPermission = {}
|
7
|
+
|
8
|
+
it 'copies the permission', ->
|
9
|
+
safariPermission = { permission: "granted" }
|
10
|
+
|
11
|
+
subject = new NotificationPermission(safariPermission)
|
12
|
+
|
13
|
+
expect(subject.permission).toEqual "granted"
|
14
|
+
|
15
|
+
it 'copies the deviceToken', ->
|
16
|
+
safariPermission = { deviceToken: "1234q" }
|
17
|
+
|
18
|
+
subject = new NotificationPermission(safariPermission)
|
19
|
+
|
20
|
+
expect(subject.deviceToken).toEqual "1234q"
|
21
|
+
|
22
|
+
describe 'no safariPermission', ->
|
23
|
+
beforeEach ->
|
24
|
+
subject = new NotificationPermission()
|
25
|
+
|
26
|
+
it 'has a default permission', ->
|
27
|
+
expect(subject.permission).toEqual "default"
|
28
|
+
|
29
|
+
it 'does not have deviceToken', ->
|
30
|
+
expect(subject.deviceToken).toBeNull()
|
31
|
+
|
32
|
+
describe 'isGranted', ->
|
33
|
+
beforeEach ->
|
34
|
+
subject = new NotificationPermission()
|
35
|
+
|
36
|
+
it 'is granted if the permission is "granted"', ->
|
37
|
+
subject.permission = 'granted'
|
38
|
+
|
39
|
+
expect(subject.isGranted()).toBe(true)
|
40
|
+
|
41
|
+
it 'is not granted if the permission is "default"', ->
|
42
|
+
subject.permission = 'default'
|
43
|
+
|
44
|
+
expect(subject.isGranted()).toBe(false)
|
45
|
+
|
46
|
+
it 'is not granted if the permission is "denied"', ->
|
47
|
+
subject.permission = 'denied'
|
48
|
+
|
49
|
+
expect(subject.isGranted()).toBe(false)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe 'APNS routes Integration Test' do
|
4
|
+
it 'routes the push package creation' do
|
5
|
+
assert_regonize_route 'post', '/apns/v1/pushPackages/web.com.example.push.id',
|
6
|
+
controller: 'crusade_rails/apns/v1/push_package',
|
7
|
+
action: 'create'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'routes the push notification subscription' do
|
11
|
+
assert_regonize_route 'post', '/apns/v1/devices/1234a/registrations/web.com.example.push.id',
|
12
|
+
controller: 'crusade_rails/apns/v1/subscription',
|
13
|
+
action: 'create'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'routes the push notification unsubscription' do
|
17
|
+
assert_regonize_route 'delete', '/apns/v1/devices/1234a/registrations/web.com.example.push.id',
|
18
|
+
controller: 'crusade_rails/apns/v1/subscription',
|
19
|
+
action: 'delete'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'routes the logs' do
|
23
|
+
assert_regonize_route 'post', '/apns/v1/log',
|
24
|
+
controller: 'crusade_rails/apns/v1/log', action: 'create'
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def engine_routes
|
29
|
+
CrusadeRails::Engine.routes
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_regonize_route(method, path, controller)
|
33
|
+
recognize = engine_routes.recognize_path path, method: method
|
34
|
+
recognize.wont_be_nil "#{method} #{path} is not recognized"
|
35
|
+
|
36
|
+
controller[:controller].must_equal recognize[:controller]
|
37
|
+
controller[:action].must_equal recognize[:action]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe CrusadeRails::NotificationService do
|
4
|
+
let(:fake_push_notification) { FakePushNotification.new }
|
5
|
+
|
6
|
+
subject { CrusadeRails::NotificationService.new fake_push_notification }
|
7
|
+
|
8
|
+
describe 'default constructor' do
|
9
|
+
it 'sets a crusade apns push notification' do
|
10
|
+
service = CrusadeRails::NotificationService.new
|
11
|
+
|
12
|
+
service.push_notification.is_a?(Crusade::APNS::PushNotification).must_be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets correctly the configuration' do
|
16
|
+
service = CrusadeRails::NotificationService.new
|
17
|
+
|
18
|
+
service.push_notification.configuration.must_be_same_as Rails.application.config.crusade
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'send_notification' do
|
23
|
+
let(:attr) { { title: 'the title', body: 'the body' } }
|
24
|
+
let(:user_id) { 1234 }
|
25
|
+
|
26
|
+
let(:subscription) { CrusadeRails::UserSubscription.new(user_id: 1234, device_token: 'aaaa', active: true) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
CrusadeRails::UserSubscription.stubs(:where).returns([])
|
30
|
+
CrusadeRails::UserSubscription.stubs(:where).with(user_id: user_id).returns([subscription])
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'notification active' do
|
34
|
+
before { subject.send_notification user_id, attr }
|
35
|
+
let(:last_sent) { fake_push_notification.last_notification }
|
36
|
+
|
37
|
+
it 'sends a push notification' do
|
38
|
+
fake_push_notification.sent?.must_be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'converts the push notification' do
|
42
|
+
last_sent.title.must_equal 'the title'
|
43
|
+
last_sent.body.must_equal 'the body'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sents to the correct device' do
|
47
|
+
last_sent.device_token.must_equal 'aaaa'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'no notification for the user' do
|
52
|
+
it 'does not send any notification' do
|
53
|
+
subject.send_notification 'unknown', attr
|
54
|
+
|
55
|
+
fake_push_notification.sent?.must_be_false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'notification inactive' do
|
60
|
+
before { subscription.active = false }
|
61
|
+
|
62
|
+
it 'does not send any notification' do
|
63
|
+
subject.send_notification user_id, attr
|
64
|
+
|
65
|
+
fake_push_notification.sent?.must_be_false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe CrusadeRails::UserSubscriptionService do
|
4
|
+
before { CrusadeRails::UserSubscription.delete_all }
|
5
|
+
after { CrusadeRails::UserSubscription.delete_all }
|
6
|
+
|
7
|
+
let(:user_id) { 123 }
|
8
|
+
|
9
|
+
describe 'register' do
|
10
|
+
subject { CrusadeRails::UserSubscriptionService.new }
|
11
|
+
|
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 }
|
15
|
+
|
16
|
+
before { registration }
|
17
|
+
|
18
|
+
it 'registers the user id' do
|
19
|
+
subscription.user_id.must_equal user_id
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'registers the user token' do
|
23
|
+
subscription.user_token.must_equal user_token
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'creates a subscription entry' do
|
27
|
+
subscription.wont_be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'does no contains a device token' do
|
31
|
+
subscription.device_token.must_be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'is not activated' do
|
35
|
+
subscription.active?.must_be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns true when the registration is successfull' do
|
39
|
+
registration.must_be_true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'subscribe' do
|
44
|
+
let(:user_token) { '1234' }
|
45
|
+
let(:device_token) { 'abcd' }
|
46
|
+
|
47
|
+
subject { CrusadeRails::UserSubscriptionService.new}
|
48
|
+
|
49
|
+
describe 'no previous subscription' do
|
50
|
+
before do
|
51
|
+
CrusadeRails::UserSubscription.new(user_id: user_id, user_token: user_token).save!
|
52
|
+
|
53
|
+
subject.subscribe user_token, device_token
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:subscription) { CrusadeRails::UserSubscription.where(user_id: user_id).first }
|
57
|
+
|
58
|
+
it 'sets the device token' do
|
59
|
+
subscription.device_token.must_equal device_token
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'activates the subscription' do
|
63
|
+
subscription.active?.must_be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it { subject.subscribe(user_token, device_token).must_be_true }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'previous subscription' do
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'subscription not found' do
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'unsubscribe' do
|
77
|
+
let(:user_token) { '1234' }
|
78
|
+
let(:device_token) { 'abcd' }
|
79
|
+
|
80
|
+
subject { CrusadeRails::UserSubscriptionService.new}
|
81
|
+
|
82
|
+
describe 'no previous subscription' do
|
83
|
+
before do
|
84
|
+
CrusadeRails::UserSubscription.new(user_id: user_id, user_token: user_token, active: true).save!
|
85
|
+
|
86
|
+
subject.unsubscribe user_token, device_token
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:subscription) { CrusadeRails::UserSubscription.where(user_id: user_id).first }
|
90
|
+
|
91
|
+
it 'unactivate the subscription' do
|
92
|
+
subscription.active?.must_be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
it { subject.unsubscribe(user_token, device_token).must_be_true }
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'previous subscription' do
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'subscription not found' do
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
class FakePushNotification
|
3
|
+
attr_reader :sent, :configuration
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
reset
|
7
|
+
end
|
8
|
+
|
9
|
+
def send notification
|
10
|
+
@sent << notification
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset
|
14
|
+
@sent = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def sent?
|
18
|
+
@sent.size > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def last_notification
|
22
|
+
@sent.last
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This file allows you to override various Teaspoon configuration directives when running from the command line. It is not
|
2
|
+
# required from within the Rails environment, so overriding directives that have been defined within the initializer
|
3
|
+
# is not possible.
|
4
|
+
#
|
5
|
+
# Set RAILS_ROOT and load the environment.
|
6
|
+
ENV["RAILS_ROOT"] = File.expand_path("../../", __FILE__)
|
7
|
+
require File.expand_path("../../test/dummy/config/environment", __FILE__)
|
8
|
+
|
9
|
+
# Provide default configuration.
|
10
|
+
#
|
11
|
+
# You can override various configuration directives defined here by using arguments with the teaspoon command.
|
12
|
+
#
|
13
|
+
# teaspoon --driver=selenium --suppress-log
|
14
|
+
# rake teaspoon DRIVER=selenium SUPPRESS_LOG=false
|
15
|
+
Teaspoon.setup do |config|
|
16
|
+
# Driver / Server
|
17
|
+
#config.driver = "phantomjs" # available: phantomjs, selenium
|
18
|
+
#config.server = nil # defaults to Rack::Server
|
19
|
+
|
20
|
+
# Behaviors
|
21
|
+
#config.server_timeout = 20 # timeout for starting the server
|
22
|
+
#config.server_port = nil # defaults to any open port unless specified
|
23
|
+
#config.fail_fast = true # abort after the first failing suite
|
24
|
+
|
25
|
+
# Output
|
26
|
+
#config.formatters = "dot" # available: dot, tap, tap_y, swayze_or_oprah
|
27
|
+
#config.suppress_log = false # suppress logs coming from console[log/error/debug]
|
28
|
+
#config.color = true
|
29
|
+
|
30
|
+
# Coverage (requires istanbul -- https://github.com/gotwarlost/istanbul)
|
31
|
+
#config.coverage = true
|
32
|
+
#config.coverage_reports = "text,html,cobertura"
|
33
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
+
|
6
|
+
require "rails/test_help"
|
7
|
+
require "minitest/spec"
|
8
|
+
require "minitest/rails"
|
9
|
+
require "minitest/mock"
|
10
|
+
require "minitest/great_expectations"
|
11
|
+
|
12
|
+
require "mocha"
|
13
|
+
|
14
|
+
module ActiveRecord::TestFixtures
|
15
|
+
def before_setup
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def after_teardown
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Rails.backtrace_cleaner.remove_silencers!
|
25
|
+
|
26
|
+
# Load support files
|
27
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|