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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1758a05336f3d5d9c4b170811ddb6ab87a12cccf
4
- data.tar.gz: 3a303c0367f99bf7ec1ced5188f7022b9fc1d171
3
+ metadata.gz: ad05870d665a99388112114ae45317f7291ada9a
4
+ data.tar.gz: 3c53eef9f8f498ed58f8c8f3bafc9e46e5eacc9e
5
5
  SHA512:
6
- metadata.gz: c69c513d634b54a466de60fb9a4afbc5a9a21ff8f4debca5e3d0c662786dc4ef1f7fc5789daa87dd39697bba6157c9f7af61b883cc29c98837acc7ccf84fd639
7
- data.tar.gz: f1f7fbf9ab9aa59fede370fb27537c5c82f31edd606b38e58b9bcef04f7b8143c7912ca44cd922500fa5a63c7aa62064fccd39113f8e409fdceb312bba017ce0
6
+ metadata.gz: 56317ffd6dbd24928a25d99d892371bb51f8f713978a6d7bf06e9f120b0d3c5da33062bf41d7247949ca91574e524fb0068524e26fe0836bacb946875487faed
7
+ data.tar.gz: c77868abdc4bb2f840fe733ca027a88e0875a23eddf97a3d4f91b31aab31d0593936ce984a2e2f1996815466280fbc5587395f9648eaf6d154e3465a7357130b
@@ -0,0 +1,38 @@
1
+ window.Crusade ||= {}
2
+
3
+ class @Crusade.AbstractNotification
4
+
5
+ requestPermission: ->
6
+ promise = $.Deferred((defer) =>
7
+ permission = @checkPermission()
8
+
9
+ @resolve(permission, defer)
10
+
11
+ ).promise()
12
+
13
+ promise.granted = promise.done
14
+ promise.denied = promise.fail
15
+
16
+ promise
17
+
18
+ checkPermission: ->
19
+ return @browserUnsupportedPermission() unless @isBrowserSupported()
20
+
21
+ @currentPermission()
22
+
23
+ wrapPermission: (safariPermission) ->
24
+ new Crusade.NotificationPermission safariPermission
25
+
26
+ resolve: (permission, defer) ->
27
+ switch permission.permission
28
+ when 'granted' then defer.resolve(permission)
29
+ when 'unauthenticated' then defer.reject(permission)
30
+ when 'denied' then defer.reject(permission)
31
+ when 'unsupported' then defer.reject(permission)
32
+ when 'default'
33
+ @requestNewPemission().
34
+ done((permission) -> defer.resolve(permission)).
35
+ fail((permission) -> defer.reject(permission))
36
+
37
+ browserUnsupportedPermission: ->
38
+ {permission: 'unsupported'}
@@ -1,4 +1,5 @@
1
+ window.Crusade ||= {}
1
2
 
2
- window.crusade =
3
+ window.Crusade.configuration =
3
4
  pushId: '<%= Rails.application.config.crusade.apns.push_id %>'
4
5
  webserviceUrl: '<%= Rails.application.config.crusade.apns.webservice_url %>'
@@ -0,0 +1,23 @@
1
+
2
+ class Crusade.LocalNotification extends Crusade.AbstractNotification
3
+
4
+ requestNewPemission: ->
5
+ $.Deferred((defer) =>
6
+ window.Notification.requestPermission (permission) =>
7
+ @resolve(@wrapPermission(permission: permission), defer)
8
+ ).promise().done((permission) ->
9
+ permission
10
+ ).fail((permission) ->
11
+ permission
12
+ )
13
+
14
+ currentPermission: ->
15
+ @wrapPermission { permission: window.Notification.permission }
16
+
17
+ notify: (title, body) ->
18
+ return 'unauthorized' unless @currentPermission().permission == 'granted'
19
+
20
+ new Notification(title, {body: body})
21
+
22
+ isBrowserSupported: ->
23
+ !! window.Notification
@@ -1,4 +1,6 @@
1
- class @NotificationPermission
1
+ window.Crusade ||= {}
2
+
3
+ class @Crusade.NotificationPermission
2
4
 
3
5
  constructor: (safariPermission) ->
4
6
  safariPermission = defaultPermission() unless safariPermission
@@ -0,0 +1,42 @@
1
+ window.Crusade ||= {}
2
+
3
+ class @Crusade.PushNotification extends Crusade.AbstractNotification
4
+
5
+ requestNewPemission: ->
6
+ $.Deferred((defer) =>
7
+ forgeryProtection = @authenticityRequest()
8
+
9
+ return @resolve(forgeryProtection, defer) if forgeryProtection.permission == 'unauthenticated'
10
+
11
+ window.safari.pushNotification.requestPermission(
12
+ window.Crusade.configuration.webserviceUrl
13
+ window.Crusade.configuration.pushId
14
+ { user_id: String(forgeryProtection.user_id), authenticity_token: forgeryProtection.authenticity_token }
15
+ (safariPermission) =>
16
+ permission = @wrapPermission safariPermission
17
+
18
+ @resolve(permission, defer)
19
+ )
20
+ ).promise()
21
+
22
+ currentPermission: ->
23
+ @wrapPermission window.safari.pushNotification.permission(window.Crusade.configuration.pushId)
24
+
25
+ authenticityRequest: ->
26
+ response = $.ajax({
27
+ url: "#{window.Crusade.configuration.webserviceUrl}/v1/pushPackages/#{window.Crusade.configuration.pushId}/new"
28
+ dataType: 'json'
29
+ method: 'get'
30
+ async: false})
31
+
32
+ return @wrapPermission(permission: 'unauthenticated') unless @isRequestSuccesful(response)
33
+
34
+ response.responseJSON.user_subscription
35
+
36
+ isRequestSuccesful: (response) ->
37
+ response.status >= 200 &&
38
+ response.status < 300 &&
39
+ response.responseJSON.user_subscription
40
+
41
+ isBrowserSupported: ->
42
+ !! window.safari && !! window.safari.pushNotification
@@ -2,21 +2,52 @@ module CrusadeRails
2
2
  module Apns
3
3
  module V1
4
4
  class PushPackageController < CrusadeRails::ApplicationController
5
- skip_before_action :verify_authenticity_token
5
+ protect_from_forgery except: :create
6
6
 
7
7
  def create
8
+ unless user_subscription_service.authenticate authenticity_token
9
+ render status: 401, nothing: true
10
+ return
11
+ end
12
+
8
13
  generator = Crusade::APNS::PushPackageGenerator.new Rails.application.config.crusade.apns
9
- user_id = json['user']
10
14
 
11
15
  Rails.logger.debug "requesting push package for user #{user_id}"
12
16
  user_token, push_package = generator.generate(user_id)
13
17
 
14
18
  Rails.logger.debug "registering push package #{user_id} - #{user_token}"
15
- CrusadeRails::UserSubscriptionService.new.register user_id, user_token
19
+ subscription = user_subscription_service.register authenticity_token, user_token
16
20
 
17
21
  Rails.logger.debug "Generation done. sending the file"
18
22
  send_data File.read(push_package), type: 'application/zip'
19
23
  end
24
+
25
+ def new
26
+ user_id = crusade_config.user_id_block.call(self)
27
+ Rails.logger.debug "generating a new user subscription for user #{user_id}"
28
+
29
+ subscription = CrusadeRails::UserSubscriptionService.new(user_id).new_subscription
30
+
31
+ render status: 201, json: { user_subscription: { user_id: user_id, authenticity_token: subscription.authenticity_token } }
32
+ end
33
+
34
+ private
35
+
36
+ def crusade_config
37
+ Rails.application.config.crusade
38
+ end
39
+
40
+ def authenticity_token
41
+ json['authenticity_token']
42
+ end
43
+
44
+ def user_id
45
+ json['user_id']
46
+ end
47
+
48
+ def user_subscription_service
49
+ @service ||= CrusadeRails::UserSubscriptionService.new(user_id)
50
+ end
20
51
  end
21
52
  end
22
53
  end
@@ -29,7 +29,11 @@ module CrusadeRails
29
29
  end
30
30
 
31
31
  def user_service
32
- @service ||= CrusadeRails::UserSubscriptionService.new
32
+ @service ||= CrusadeRails::UserSubscriptionService.new crusade_config.user_id_block.call(self)
33
+ end
34
+
35
+ def crusade_config
36
+ Rails.application.config.crusade
33
37
  end
34
38
  end
35
39
  end
@@ -4,11 +4,11 @@ module CrusadeRails
4
4
  protected
5
5
 
6
6
  def body
7
- request.body.read
7
+ @body ||= request.body.read
8
8
  end
9
9
 
10
10
  def json
11
- JSON.parse body
11
+ @json_body ||= JSON.parse body
12
12
  end
13
13
  end
14
14
  end
@@ -1,10 +1,30 @@
1
+ require 'securerandom'
2
+
1
3
  module CrusadeRails
2
4
  class UserSubscriptionService
3
- def register user_id, user_token
4
- subscription = CrusadeRails::UserSubscription.new({
5
- user_token: user_token,
6
- user_id: user_id
7
- })
5
+ attr_reader :user_id
6
+
7
+ def initialize(user_id = nil)
8
+ self.user_id = Integer user_id
9
+
10
+ raise ArgumentError unless user_id
11
+ end
12
+
13
+ def new_subscription
14
+ subscription = UserSubscription.where(user_id: user_id).last ||
15
+ create_user_subscription
16
+
17
+ subscription.authenticity_token = generate_authenticity_token
18
+
19
+ subscription.save # do something if the save fails
20
+ subscription
21
+ end
22
+
23
+ def register authenticity_token, user_token
24
+ subscription = UserSubscription.where(user_id: user_id, authenticity_token: authenticity_token).first
25
+ return :unauthenticated unless subscription
26
+
27
+ subscription.update_attributes user_token: user_token
8
28
  subscription.save
9
29
  end
10
30
 
@@ -25,12 +45,26 @@ module CrusadeRails
25
45
  subscription.save
26
46
  end
27
47
 
48
+ def authenticate authenticity_token
49
+ UserSubscription.where(user_id: user_id, authenticity_token: authenticity_token).any?
50
+ end
51
+
28
52
  private
29
53
 
30
- attr_accessor :user_id
54
+ attr_writer :user_id
31
55
 
32
56
  def find_subscription_by_user_token(user_token)
33
- CrusadeRails::UserSubscription.where(user_token: user_token).first
57
+ UserSubscription.where(user_token: user_token).first
58
+ end
59
+
60
+ def generate_authenticity_token
61
+ SecureRandom.base64(100)
62
+ end
63
+
64
+ def create_user_subscription
65
+ subscription = UserSubscription.new({
66
+ user_id: user_id
67
+ })
34
68
  end
35
69
  end
36
70
  end
@@ -5,6 +5,8 @@ CrusadeRails::Engine.routes.draw do
5
5
  namespace "v1" do
6
6
  post "pushPackages/#{Rails.application.config.crusade.apns.push_id}",
7
7
  to: "push_package#create", as: "apns_push_package"
8
+ get "pushPackages/#{Rails.application.config.crusade.apns.push_id}/new",
9
+ to: "push_package#new", as: "apns_push_package_authorization"
8
10
 
9
11
  post "/devices/:device_token/registrations/#{Rails.application.config.crusade.apns.push_id}",
10
12
  to: "subscription#create", as: "apns_push_registration"
@@ -2,6 +2,7 @@ class CreateCrusadeRailsUserSubscriptions < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :crusade_rails_user_subscriptions do |t|
4
4
  t.integer :user_id
5
+ t.string :authenticity_token
5
6
  t.string :user_token
6
7
  t.string :device_token
7
8
  t.boolean :active
@@ -1,4 +1,5 @@
1
1
  require "crusade_rails/engine"
2
+ require "crusade_rails/configuration"
2
3
 
3
4
  module CrusadeRails
4
5
  end
@@ -0,0 +1,45 @@
1
+
2
+ module CrusadeRails
3
+ def self.config &block
4
+ c = ConfigurationWrapper.config &block
5
+ Rails.application.config.crusade = c
6
+ end
7
+
8
+ private
9
+
10
+ class ConfigurationWrapper
11
+ attr_accessor :user_id_block
12
+
13
+ def initialize
14
+ self.crusade = Crusade::Configuration.new
15
+ end
16
+
17
+ def plugins= plugins
18
+ crusade.plugins = Array(plugins).inject({}) do |memo, plugin|
19
+ memo.update plugin => File.join(Rails.root, 'config', "crusade-#{plugin}.yml")
20
+ end
21
+ end
22
+
23
+ def self.config &block
24
+ config = new
25
+ yield config
26
+ config
27
+ end
28
+
29
+ def method_missing(m, *args, &block)
30
+ if crusade.respond_to? m
31
+ crusade.send m, *args, &block
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ def respond_to? method
38
+ super || crusade.respond_to?(method)
39
+ end
40
+
41
+ private
42
+
43
+ attr_accessor :crusade
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module CrusadeRails
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.2"
3
3
  end
@@ -1,6 +1,6 @@
1
- Crusade.config do |config|
1
+ CrusadeRails.config do |config|
2
2
  config.env = Rails.env
3
- config.plugins = { apns: "#{Rails.root}/config/crusade-apns.yml" }
3
+ config.plugins = []
4
4
 
5
- Rails.application.config.crusade = config
5
+ config.user_id_block = -> { |controller| 1 }
6
6
  end
@@ -1,16 +1,19 @@
1
1
  require 'test_helper'
2
2
 
3
3
  describe CrusadeRails::Apns::V1::PushPackageController do
4
+ let(:service) { stub_everything(:user_service) }
5
+ let(:user_id) { 10 }
6
+ let(:authenticity_token) { 'aaaaa'}
4
7
 
5
- before { @routes = CrusadeRails::Engine.routes }
8
+ before do
9
+ @routes = CrusadeRails::Engine.routes
10
+ CrusadeRails::UserSubscriptionService.stubs(:new).with(user_id).returns(service)
11
+ end
6
12
 
7
13
  describe "create action" do
8
14
  let(:temp_file) { '/tmp/text.txt' }
9
- let(:user_id) { 10 }
10
15
  let(:user_token) { '123zz' }
11
16
 
12
- let(:service) { stub_everything(:user_service) }
13
-
14
17
  before do
15
18
  File.stubs(:read).with(temp_file).returns('test data')
16
19
 
@@ -18,9 +21,9 @@ describe CrusadeRails::Apns::V1::PushPackageController do
18
21
  generator.stubs(:generate).with(user_id).returns [user_token, temp_file]
19
22
  Crusade::APNS::PushPackageGenerator.stubs(:new).returns generator
20
23
 
21
- CrusadeRails::UserSubscriptionService.stubs(:new).returns(service)
24
+ service.stubs(:authenticate).returns(true)
22
25
 
23
- request.env['RAW_POST_DATA'] = { user: user_id }.to_json
26
+ request.env['RAW_POST_DATA'] = { user_id: user_id, authenticity_token: authenticity_token }.to_json
24
27
 
25
28
  post :create, :format => :json
26
29
  end
@@ -33,9 +36,38 @@ describe CrusadeRails::Apns::V1::PushPackageController do
33
36
  end
34
37
 
35
38
  it 'register the user_id push package request' do
36
- service.expects(:register).with(user_id, user_token)
39
+ service.expects(:register).with(authenticity_token, user_token)
37
40
 
38
41
  post :create, :format => :json
39
42
  end
43
+
44
+ describe 'unauthenticated registration' do
45
+ before do
46
+ service.stubs(:authenticate).returns(false)
47
+
48
+ post :create, :format => :json
49
+ end
50
+
51
+ it { response.status.must_equal 401 }
52
+ it { response.body.strip.must_equal '' }
53
+ end
54
+ end
55
+
56
+ describe 'new' do
57
+ before do
58
+ Rails.application.config.crusade.user_id_block = lambda { |c| user_id }
59
+
60
+ service.stubs(:new_subscription).returns OpenStruct.new(authenticity_token: authenticity_token)
61
+
62
+ get :new
63
+ end
64
+
65
+ let(:json) { JSON.parse response.body }
66
+
67
+ it { response.status.must_equal 201 }
68
+ it { response.content_type.must_equal 'application/json' }
69
+ it 'generate a json message with the authenticity_token & user_id' do
70
+ json.must_equal({ 'user_subscription' => { "user_id" => user_id, "authenticity_token" => authenticity_token}})
71
+ end
40
72
  end
41
73
  end