hootenanny 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +5 -0
  3. data/Gemfile +5 -7
  4. data/Gemfile.lock +46 -28
  5. data/app/controllers/hootenanny/notifications_controller.rb +31 -0
  6. data/app/controllers/hootenanny/parameters.rb +16 -0
  7. data/app/controllers/hootenanny/subscriptions_controller.rb +24 -3
  8. data/app/models/hootenanny/publish_notification.rb +90 -0
  9. data/app/models/hootenanny/subscription.rb +72 -23
  10. data/config/routes.rb +2 -1
  11. data/db/migrate/20130607182642_add_started_at_and_lease_duration_to_subscriptions.rb +15 -0
  12. data/db/migrate/20130608225621_add_hmac_secret_to_subscription.rb +5 -0
  13. data/db/migrate/20130611235218_add_publish_notifications.rb +9 -0
  14. data/db/migrate/20130612153138_add_timestamps_to_publish_notification.rb +5 -0
  15. data/db/migrate/20130705200729_add_processed_flag_to_publish_notifications.rb +6 -0
  16. data/db/migrate/20130711061329_switch_publish_notification_process_state_from_boolean_to_string.rb +11 -0
  17. data/db/migrate/20130711061558_add_index_to_notifications_state.rb +5 -0
  18. data/hootenanny.gemspec +6 -2
  19. data/lib/hootenanny/configuration.rb +43 -0
  20. data/lib/hootenanny/correspondent.rb +44 -0
  21. data/lib/hootenanny/errors.rb +42 -1
  22. data/lib/hootenanny/feed.rb +75 -0
  23. data/lib/hootenanny/feed/atom_feed.rb +18 -0
  24. data/lib/hootenanny/feed/atom_feed_item.rb +8 -0
  25. data/lib/hootenanny/feed/digest_feed.rb +14 -0
  26. data/lib/hootenanny/feed/digest_feed_item.rb +11 -0
  27. data/lib/hootenanny/feed/feed_item.rb +30 -0
  28. data/lib/hootenanny/feed/file.rb +66 -0
  29. data/lib/hootenanny/feed/json_feed.rb +48 -0
  30. data/lib/hootenanny/feed/json_feed_item.rb +8 -0
  31. data/lib/hootenanny/feed/null_feed.rb +27 -0
  32. data/lib/hootenanny/feed/rss_feed.rb +52 -0
  33. data/lib/hootenanny/feed/rss_feed_item.rb +8 -0
  34. data/lib/hootenanny/feed_store.rb +30 -0
  35. data/lib/hootenanny/feed_store/file_feed_store.rb +55 -0
  36. data/lib/hootenanny/feed_store/web_feed_store.rb +42 -0
  37. data/lib/hootenanny/hub.rb +116 -22
  38. data/lib/hootenanny/publish_notification_expiration_policy.rb +17 -0
  39. data/lib/hootenanny/request.rb +40 -0
  40. data/lib/hootenanny/request/publish_notification.rb +94 -0
  41. data/lib/hootenanny/request/subscription.rb +153 -0
  42. data/lib/hootenanny/subscription_delivery.rb +47 -0
  43. data/lib/hootenanny/topic.rb +38 -0
  44. data/lib/hootenanny/topic_synchronizer.rb +71 -0
  45. data/lib/hootenanny/uri.rb +53 -0
  46. data/lib/hootenanny/verification.rb +108 -0
  47. data/lib/hootenanny/version.rb +1 -1
  48. data/spec/dummy/config/database.yml +12 -6
  49. data/spec/dummy/db/migrate/20130607183149_add_started_at_and_lease_duration_to_subscriptions.hootenanny.rb +16 -0
  50. data/spec/dummy/db/migrate/20130608231253_add_hmac_secret_to_subscription.hootenanny.rb +6 -0
  51. data/spec/dummy/db/migrate/20130611235546_add_publish_notifications.hootenanny.rb +10 -0
  52. data/spec/dummy/db/migrate/20130612153353_add_timestamps_to_publish_notification.hootenanny.rb +6 -0
  53. data/spec/dummy/db/migrate/20130705200832_add_processed_flag_to_publish_notifications.hootenanny.rb +7 -0
  54. data/spec/dummy/db/migrate/20130711061518_switch_publish_notification_process_state_from_boolean_to_string.hootenanny.rb +12 -0
  55. data/spec/dummy/db/migrate/20130711061629_add_index_to_notifications_state.hootenanny.rb +6 -0
  56. data/spec/factories/publish_notification.rb +13 -0
  57. data/spec/factories/requests/publish_notification.rb +11 -0
  58. data/spec/factories/requests/subscription.rb +46 -0
  59. data/spec/factories/subscription.rb +14 -2
  60. data/spec/factories/verification.rb +15 -0
  61. data/spec/features/publishers/can_notify_the_hub_of_content_updates_spec.rb +58 -0
  62. data/spec/features/subscribers/are_protected_from_unwarranted_subscriptions_spec.rb +59 -0
  63. data/spec/features/subscribers/can_receive_distributions_of_topic_content_spec.rb +175 -0
  64. data/spec/features/subscribers/can_subscribe_to_a_topic_spec.rb +76 -7
  65. data/spec/fixtures/feeds/atom/97d79220f68b4bf27.atom +0 -0
  66. data/spec/fixtures/feeds/atom/sample_feed.atom +51 -0
  67. data/spec/fixtures/feeds/digest/97d79220f68b4bf27.digest +1 -0
  68. data/spec/fixtures/feeds/digest/complete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest +6 -0
  69. data/spec/fixtures/feeds/digest/incomplete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest +5 -0
  70. data/spec/fixtures/feeds/digest/sample_feed.digest +6 -0
  71. data/spec/fixtures/feeds/json/97d79220f68b4bf27.json +1 -0
  72. data/spec/fixtures/feeds/json/feed_with_one_item.json +21 -0
  73. data/spec/fixtures/feeds/json/sample_feed.json +30 -0
  74. data/spec/fixtures/feeds/rss/5b187098da59f077f/97d79220f68b4bf27.rss +21 -0
  75. data/spec/fixtures/feeds/rss/97d79220f68b4bf27.rss +0 -0
  76. data/spec/fixtures/feeds/rss/feed_with_one_item.rss +15 -0
  77. data/spec/fixtures/feeds/rss/minimal_feed.rss +12 -0
  78. data/spec/fixtures/feeds/rss/sample_feed.rss +22 -0
  79. data/spec/fixtures/feeds/rss/sample_feed_2.rss +22 -0
  80. data/spec/lib/hootenanny/configuration_spec.rb +7 -0
  81. data/spec/lib/hootenanny/correspondent_spec.rb +94 -0
  82. data/spec/lib/hootenanny/errors_spec.rb +21 -0
  83. data/spec/lib/hootenanny/feed/atom_feed_item_spec.rb +9 -0
  84. data/spec/lib/hootenanny/feed/atom_feed_spec.rb +40 -0
  85. data/spec/lib/hootenanny/feed/digest_feed_item_spec.rb +9 -0
  86. data/spec/lib/hootenanny/feed/digest_feed_spec.rb +40 -0
  87. data/spec/lib/hootenanny/feed/feed_item_spec.rb +49 -0
  88. data/spec/lib/hootenanny/feed/file_spec.rb +66 -0
  89. data/spec/lib/hootenanny/feed/json_feed_item_spec.rb +9 -0
  90. data/spec/lib/hootenanny/feed/json_feed_spec.rb +128 -0
  91. data/spec/lib/hootenanny/feed/null_feed_spec.rb +9 -0
  92. data/spec/lib/hootenanny/feed/rss_feed_item_spec.rb +9 -0
  93. data/spec/lib/hootenanny/feed/rss_feed_spec.rb +143 -0
  94. data/spec/lib/hootenanny/feed_spec.rb +159 -0
  95. data/spec/lib/hootenanny/feed_store/file_feed_store_spec.rb +58 -0
  96. data/spec/lib/hootenanny/feed_store/web_feed_store_spec.rb +47 -0
  97. data/spec/lib/hootenanny/feed_store_spec.rb +27 -0
  98. data/spec/lib/hootenanny/hub_spec.rb +73 -0
  99. data/spec/lib/hootenanny/publish_notification_expiration_policy_spec.rb +35 -0
  100. data/spec/lib/hootenanny/request/publish_notification_spec.rb +43 -0
  101. data/spec/lib/hootenanny/request/subscription_spec.rb +89 -0
  102. data/spec/lib/hootenanny/request_spec.rb +21 -0
  103. data/spec/lib/hootenanny/subscription_delivery_spec.rb +54 -0
  104. data/spec/lib/hootenanny/topic_spec.rb +15 -0
  105. data/spec/lib/hootenanny/topic_synchronizer_spec.rb +98 -0
  106. data/spec/lib/hootenanny/uri_spec.rb +32 -0
  107. data/spec/lib/hootenanny/verification_spec.rb +92 -0
  108. data/spec/models/hootenanny/publish_notification_spec.rb +55 -0
  109. data/spec/models/hootenanny/subscription_spec.rb +58 -19
  110. data/spec/support/verification.rb +63 -0
  111. metadata +231 -14
  112. data/spec/controllers/hootenanny/hub_spec.rb +0 -15
@@ -0,0 +1,92 @@
1
+ require 'rspectacular'
2
+ require 'support/verification'
3
+ require 'hootenanny/verification'
4
+
5
+ module Hootenanny
6
+ describe Verification do
7
+ context 'when the verification representation can be verified' do
8
+ before { confirmed_verification 'mymode',
9
+ 'http://example.com',
10
+ 'http://example.org' }
11
+
12
+ it 'can determine that it is verified' do
13
+ verification = build(:verification, url: 'http://example.com',
14
+ topic: 'http://example.org',
15
+ mode: 'mymode')
16
+
17
+ expect(verification).to be_verified
18
+ end
19
+ end
20
+
21
+ context 'when the verification representation cannot be verified' do
22
+ before { unconfirmed_verification 'mymode',
23
+ 'http://example.com',
24
+ 'http://example.org' }
25
+
26
+ it 'can determine that it is verified' do
27
+ verification = build(:verification, url: 'http://example.com',
28
+ topic: 'http://example.org',
29
+ mode: 'mymode')
30
+
31
+ expect(verification).not_to be_verified
32
+ end
33
+ end
34
+
35
+ context 'when the verification representation cannot be verified' do
36
+ before { unverified_verification 'mymode',
37
+ 'http://example.com',
38
+ 'http://example.org' }
39
+
40
+ it 'can determine that it is verified' do
41
+ verification = build(:verification, url: 'http://example.com',
42
+ topic: 'http://example.org',
43
+ mode: 'mymode')
44
+
45
+ expect(verification).not_to be_verified
46
+ end
47
+ end
48
+
49
+ it 'appends the mode to the URI' do
50
+ verification = build(:verification, mode: 'foo')
51
+
52
+ expect(verification.uri.query).to include 'hub.mode=foo'
53
+ end
54
+
55
+ it 'appends the topic to the URI' do
56
+ verification = build(:verification, topic: 'http://topic.com')
57
+
58
+ expect(verification.uri.query).to include 'hub.topic=http%3A%2F%2Ftopic.com'
59
+ end
60
+
61
+ it 'appends the challenge token to the URI' do
62
+ verification = build(:verification)
63
+
64
+ expect(verification.uri.query).to match %r{hub.challenge=[0-9a-f]{32}}
65
+ end
66
+
67
+ it 'appends the verify token to the URI if it is passed in' do
68
+ verification = build(:verification, requester_token: 'foo')
69
+
70
+ expect(verification.uri.query).to include 'hub.verify_token=foo'
71
+ end
72
+
73
+ it 'does not append the verify token to the URI if it is not passed in' do
74
+ verification = build(:verification, requester_token: nil)
75
+
76
+ expect(verification.uri.query).not_to include 'hub.verify_token'
77
+ end
78
+
79
+ it 'appends the verification parameters to the URI even if they already exist in the subscription URI' do
80
+ verification = build(:verification, url: 'http://example.com?hub.mode=foo',
81
+ mode: 'mymode')
82
+
83
+ expect(verification.uri.to_s).to match %r{http://example.com\?hub.mode=foo&hub.mode=mymode.+}
84
+ end
85
+
86
+ it 'does not add an unnecessary ampersand to the URL if the :url has no query component' do
87
+ verification = build(:verification, url: 'http://example.com')
88
+
89
+ expect(verification.uri.to_s).to match %r{http://example.com\?[^&]}
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,55 @@
1
+ require 'rspectacular/spec_helpers/active_record_basic'
2
+ require 'hootenanny/publish_notification'
3
+
4
+ module Hootenanny
5
+ describe PublishNotification do
6
+ context 'when no notifications exist' do
7
+ before { expect(PublishNotification.count).to be_zero }
8
+
9
+ it 'can create a notification based on the topic' do
10
+ PublishNotification.notify('http://mytopic')
11
+
12
+ retrieved_notification = PublishNotification.for('http://mytopic').first
13
+
14
+ expect(PublishNotification.count).to eql 1
15
+ expect(retrieved_notification.topic).to eql 'http://mytopic'
16
+ end
17
+ end
18
+
19
+ context 'when a notification exists' do
20
+ let!(:existing_notification) { create :publish_notification,
21
+ :topic => 'http://mytopic' }
22
+
23
+ it 'can find the notification based on the topic' do
24
+ retrieved_notification = PublishNotification.for('http://mytopic').first
25
+
26
+ expect(retrieved_notification).to eql existing_notification
27
+ end
28
+
29
+ it 'can updates the existing notification', :time_mock => Time.utc(2012, 7, 26, 12, 0, 0) do
30
+ PublishNotification.notify('http://mytopic')
31
+
32
+ retrieved_notification = PublishNotification.for('http://mytopic').first
33
+
34
+ expect(PublishNotification.count).to eql 1
35
+ expect(retrieved_notification.updated_at).to eql Time.utc(2012, 7, 26, 12, 0, 0)
36
+ end
37
+ end
38
+
39
+ context 'when multiple notifications exist' do
40
+ let!(:existing_notifications) {[
41
+ create(:publish_notification, :topic => 'mytopic'),
42
+ create(:publish_notification, :topic => 'myothertopic')
43
+ ]}
44
+
45
+ it 'can find the notification based on the topic' do
46
+ retrieved_notifications = PublishNotification.for([
47
+ 'mytopic',
48
+ 'myothertopic'
49
+ ]).all
50
+
51
+ expect(retrieved_notifications).to eql existing_notifications
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,31 +1,46 @@
1
1
  require 'rspectacular/spec_helpers/active_record_basic'
2
2
  require 'hootenanny/subscription'
3
3
 
4
- Subscription ||= Hootenanny::Subscription
4
+ module Hootenanny
5
+ describe Subscription do
6
+ it 'can find itself based on its topic if it is active' do
7
+ create(:subscription, :active,
8
+ :topic => 'http://topic.com')
5
9
 
6
- describe Hootenanny::Subscription do
7
- it 'can find itself based on its topic' do
8
- existing_subscription = create(:subscription, :topic => 'my_topic')
9
-
10
- found_subscriptions = Subscription.to('my_topic')
10
+ found_subscriptions = Subscription.to('http://topic.com')
11
11
  found_subscription = found_subscriptions.first
12
12
 
13
13
  expect(found_subscriptions).to have(1).item
14
14
 
15
15
  expect(found_subscription).to be_a Subscription
16
- expect(found_subscription.topic).to eql 'my_topic'
16
+ expect(found_subscription.topic).to eql 'http://topic.com'
17
+ end
18
+
19
+ it 'cannot find itself based on its topic if it is inactive' do
20
+ create(:subscription, :inactive,
21
+ :topic => 'http://topic.com')
22
+
23
+ found_subscriptions = Subscription.to('http://topic.com')
24
+
25
+ expect(found_subscriptions).to be_empty
17
26
  end
18
27
 
19
28
  context 'when a subscription does not exist for a given subscriber and topic' do
20
29
  before { expect(Subscription.count).to be_zero }
21
30
 
22
- it 'can assign a subscription to a given subscriber and topic' do
23
- assigned_subscription = Subscription.assign( subscriber: 'http://example.com/my_callback',
24
- to: 'http://example.org/my_topic')
31
+ it 'can subscribe a subscription to a given subscriber and topic', :time_mock => Time.utc(2012, 7, 20, 12, 0, 0) do
32
+ subscribeed_subscription = Subscription.subscribe(
33
+ subscriber: 'http://example.com/my_callback',
34
+ to: 'http://example.org/my_topic',
35
+ lease_duration: 12,
36
+ digest_secret: 'secret')
25
37
 
26
- expect(assigned_subscription).to be_persisted
27
- expect(assigned_subscription.subscriber).to eql 'http://example.com/my_callback'
28
- expect(assigned_subscription.topic).to eql 'http://example.org/my_topic'
38
+ expect(subscribeed_subscription).to be_persisted
39
+ expect(subscribeed_subscription.subscriber).to eql URI.parse('http://example.com/my_callback')
40
+ expect(subscribeed_subscription.topic).to eql 'http://example.org/my_topic'
41
+ expect(subscribeed_subscription.lease_duration).to eql 12
42
+ expect(subscribeed_subscription.digest_secret).to eql 'secret'
43
+ expect(subscribeed_subscription.started_at).to eql Time.utc(2012, 7, 20, 12, 0, 0)
29
44
  end
30
45
  end
31
46
 
@@ -35,16 +50,40 @@ describe Hootenanny::Subscription do
35
50
  topic: 'http://example.org/my_topic')
36
51
  end
37
52
 
38
- it 'can does not create a new subscription but rather returns the current one' do
39
- assigned_subscription = Subscription.assign( subscriber: 'http://example.com/my_callback',
40
- to: 'http://example.org/my_topic')
53
+ it 'does not create a new subscription but rather returns the current one' do
54
+ subscribeed_subscription = Subscription.subscribe(
55
+ subscriber: 'http://example.com/my_callback',
56
+ to: 'http://example.org/my_topic',
57
+ lease_duration: 30)
41
58
 
42
- expect(assigned_subscription).to eql existing_subscription
59
+ expect(subscribeed_subscription).to eql existing_subscription
60
+ end
61
+
62
+ it 'updates the attributes of the current subscription to match the new subscription request' do
63
+ expect(existing_subscription.lease_duration).not_to eql 30
64
+
65
+ subscribeed_subscription = Subscription.subscribe(
66
+ subscriber: 'http://example.com/my_callback',
67
+ to: 'http://example.org/my_topic',
68
+ lease_duration: 30)
69
+
70
+ expect(subscribeed_subscription.lease_duration).to eql 30
71
+ end
72
+
73
+ it 'updates the starting date of the subscription to be the current time', :time_mock => Time.utc(2012, 6, 20, 12, 0, 0) do
74
+ subscribeed_subscription = Subscription.subscribe(
75
+ subscriber: 'http://example.com/my_callback',
76
+ to: 'http://example.org/my_topic',
77
+ lease_duration: 30)
78
+
79
+ expect(subscribeed_subscription.started_at).to eql Time.utc(2012, 6, 20, 12, 0, 0)
43
80
  end
44
81
  end
45
82
 
46
83
  it 'properly handles the error when the URIs are invalid' do
47
- expect { Subscription.assign( subscriber: 'http://iluvhamburgerz!!!',
48
- to: 'http://gimmeburger!!!') }.to raise_error Hootenanny::SubscriptionAssignmentError
84
+ expect { Subscription.subscribe( subscriber: 'http://iluvhamburgerz!!!',
85
+ to: 'http://gimmeburger!!!') }
86
+ .to raise_error Hootenanny::URI::InvalidError
49
87
  end
50
88
  end
89
+ end
@@ -0,0 +1,63 @@
1
+ def unconfirmed_subscription_verification(callback_url, topic_url)
2
+ unconfirmed_verification('subscribe', callback_url, topic_url)
3
+ end
4
+
5
+ def unverified_subscription_verification(callback_url, topic_url)
6
+ unverified_verification('subscribe', callback_url, topic_url)
7
+ end
8
+
9
+ def confirmed_subscription_verification(callback_url, topic_url)
10
+ confirmed_verification('subscribe', callback_url, topic_url)
11
+ end
12
+
13
+ def confirmed_verification(mode, callback_url, topic_url, options = {})
14
+ stub_request(:get, /#{callback_url}.*/)
15
+ .with do |request|
16
+ params = request.uri.query_values
17
+
18
+ params['hub.mode'] == mode &&
19
+ params['hub.topic'] == topic_url &&
20
+ params['hub.challenge'].match(/[0-9a-f]{32}/) &&
21
+ params['hub.verify_token'] == options[:requester_token]
22
+ end
23
+ .to_return do |request|
24
+ {
25
+ status: 200,
26
+ body: request.uri.query_values['hub.challenge'],
27
+ }
28
+ end
29
+ end
30
+
31
+ def unconfirmed_verification(mode, callback_url, topic_url)
32
+ stub_request(:get, /#{callback_url}.*/)
33
+ .with do |request|
34
+ params = request.uri.query_values
35
+
36
+ params['hub.mode'] == mode &&
37
+ params['hub.topic'] == topic_url &&
38
+ params['hub.challenge'].match(/[0-9a-f]{32}/)
39
+ end
40
+ .to_return do |request|
41
+ {
42
+ status: 404,
43
+ body: nil,
44
+ }
45
+ end
46
+ end
47
+
48
+ def unverified_verification(mode, callback_url, topic_url)
49
+ stub_request(:get, /#{callback_url}.*/)
50
+ .with do |request|
51
+ params = request.uri.query_values
52
+
53
+ params['hub.mode'] == mode &&
54
+ params['hub.topic'] == topic_url &&
55
+ params['hub.challenge'].match(/[0-9a-f]{32}/)
56
+ end
57
+ .to_return do |request|
58
+ {
59
+ status: 200,
60
+ body: 'aaaaaaaaaaaaaaaaaaaaa',
61
+ }
62
+ end
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hootenanny
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-23 00:00:00.000000000 Z
12
+ date: 2013-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.2.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: faraday
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.8.7
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.7
62
+ - !ruby/object:Gem::Dependency
63
+ name: chronological
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.0.0beta10
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.0.0beta10
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: pg
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -60,29 +92,29 @@ dependencies:
60
92
  - !ruby/object:Gem::Version
61
93
  version: '0'
62
94
  - !ruby/object:Gem::Dependency
63
- name: sqlite3
95
+ name: rspec-rails
64
96
  requirement: !ruby/object:Gem::Requirement
65
97
  none: false
66
98
  requirements:
67
- - - ! '>='
99
+ - - ~>
68
100
  - !ruby/object:Gem::Version
69
- version: '0'
101
+ version: 2.14.0.rc1
70
102
  type: :development
71
103
  prerelease: false
72
104
  version_requirements: !ruby/object:Gem::Requirement
73
105
  none: false
74
106
  requirements:
75
- - - ! '>='
107
+ - - ~>
76
108
  - !ruby/object:Gem::Version
77
- version: '0'
109
+ version: 2.14.0.rc1
78
110
  - !ruby/object:Gem::Dependency
79
- name: rspec-rails
111
+ name: rspec
80
112
  requirement: !ruby/object:Gem::Requirement
81
113
  none: false
82
114
  requirements:
83
115
  - - ~>
84
116
  - !ruby/object:Gem::Version
85
- version: '2.13'
117
+ version: 2.14.0.rc1
86
118
  type: :development
87
119
  prerelease: false
88
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +122,7 @@ dependencies:
90
122
  requirements:
91
123
  - - ~>
92
124
  - !ruby/object:Gem::Version
93
- version: '2.13'
125
+ version: 2.14.0.rc1
94
126
  - !ruby/object:Gem::Dependency
95
127
  name: database_cleaner
96
128
  requirement: !ruby/object:Gem::Requirement
@@ -139,6 +171,38 @@ dependencies:
139
171
  - - ~>
140
172
  - !ruby/object:Gem::Version
141
173
  version: '4.2'
174
+ - !ruby/object:Gem::Dependency
175
+ name: timecop
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ~>
180
+ - !ruby/object:Gem::Version
181
+ version: 0.6.1
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ~>
188
+ - !ruby/object:Gem::Version
189
+ version: 0.6.1
190
+ - !ruby/object:Gem::Dependency
191
+ name: webmock
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ~>
196
+ - !ruby/object:Gem::Version
197
+ version: '1.11'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ~>
204
+ - !ruby/object:Gem::Version
205
+ version: '1.11'
142
206
  description: A drop-in PubSubHubBub-compliant Rails Engine for easy hubbubing.
143
207
  email: support@thekompanee.com
144
208
  executables: []
@@ -149,26 +213,62 @@ files:
149
213
  - .gitignore
150
214
  - .rspec
151
215
  - .ruby-version
216
+ - .travis.yml
152
217
  - Gemfile
153
218
  - Gemfile.lock
154
219
  - README.md
155
220
  - Rakefile
221
+ - app/controllers/hootenanny/notifications_controller.rb
222
+ - app/controllers/hootenanny/parameters.rb
156
223
  - app/controllers/hootenanny/subscriptions_controller.rb
224
+ - app/models/hootenanny/publish_notification.rb
157
225
  - app/models/hootenanny/subscription.rb
158
226
  - config/routes.rb
159
227
  - db/migrate/20130522014217_create_subscription_table.rb
160
228
  - db/migrate/20130522020623_rename_subscriptions_table.rb
161
229
  - db/migrate/20130522235837_add_topic_to_subscriptions.rb
162
230
  - db/migrate/20130523032940_add_subscriber_to_subscriptions.rb
231
+ - db/migrate/20130607182642_add_started_at_and_lease_duration_to_subscriptions.rb
232
+ - db/migrate/20130608225621_add_hmac_secret_to_subscription.rb
233
+ - db/migrate/20130611235218_add_publish_notifications.rb
234
+ - db/migrate/20130612153138_add_timestamps_to_publish_notification.rb
235
+ - db/migrate/20130705200729_add_processed_flag_to_publish_notifications.rb
236
+ - db/migrate/20130711061329_switch_publish_notification_process_state_from_boolean_to_string.rb
237
+ - db/migrate/20130711061558_add_index_to_notifications_state.rb
163
238
  - hootenanny.gemspec
164
239
  - lib/hootenanny.rb
240
+ - lib/hootenanny/configuration.rb
241
+ - lib/hootenanny/correspondent.rb
165
242
  - lib/hootenanny/engine.rb
166
243
  - lib/hootenanny/errors.rb
244
+ - lib/hootenanny/feed.rb
245
+ - lib/hootenanny/feed/atom_feed.rb
246
+ - lib/hootenanny/feed/atom_feed_item.rb
247
+ - lib/hootenanny/feed/digest_feed.rb
248
+ - lib/hootenanny/feed/digest_feed_item.rb
249
+ - lib/hootenanny/feed/feed_item.rb
250
+ - lib/hootenanny/feed/file.rb
251
+ - lib/hootenanny/feed/json_feed.rb
252
+ - lib/hootenanny/feed/json_feed_item.rb
253
+ - lib/hootenanny/feed/null_feed.rb
254
+ - lib/hootenanny/feed/rss_feed.rb
255
+ - lib/hootenanny/feed/rss_feed_item.rb
256
+ - lib/hootenanny/feed_store.rb
257
+ - lib/hootenanny/feed_store/file_feed_store.rb
258
+ - lib/hootenanny/feed_store/web_feed_store.rb
167
259
  - lib/hootenanny/hub.rb
260
+ - lib/hootenanny/publish_notification_expiration_policy.rb
261
+ - lib/hootenanny/request.rb
262
+ - lib/hootenanny/request/publish_notification.rb
263
+ - lib/hootenanny/request/subscription.rb
264
+ - lib/hootenanny/subscription_delivery.rb
265
+ - lib/hootenanny/topic.rb
266
+ - lib/hootenanny/topic_synchronizer.rb
267
+ - lib/hootenanny/uri.rb
268
+ - lib/hootenanny/verification.rb
168
269
  - lib/hootenanny/version.rb
169
270
  - lib/tasks/hootenanny_tasks.rake
170
271
  - script/rails
171
- - spec/controllers/hootenanny/hub_spec.rb
172
272
  - spec/dummy/README.rdoc
173
273
  - spec/dummy/Rakefile
174
274
  - spec/dummy/app/assets/javascripts/application.js
@@ -199,15 +299,74 @@ files:
199
299
  - spec/dummy/db/migrate/20130522020714_rename_subscriptions_table.hootenanny.rb
200
300
  - spec/dummy/db/migrate/20130523000104_add_topic_to_subscriptions.hootenanny.rb
201
301
  - spec/dummy/db/migrate/20130523053741_add_subscriber_to_subscriptions.hootenanny.rb
302
+ - spec/dummy/db/migrate/20130607183149_add_started_at_and_lease_duration_to_subscriptions.hootenanny.rb
303
+ - spec/dummy/db/migrate/20130608231253_add_hmac_secret_to_subscription.hootenanny.rb
304
+ - spec/dummy/db/migrate/20130611235546_add_publish_notifications.hootenanny.rb
305
+ - spec/dummy/db/migrate/20130612153353_add_timestamps_to_publish_notification.hootenanny.rb
306
+ - spec/dummy/db/migrate/20130705200832_add_processed_flag_to_publish_notifications.hootenanny.rb
307
+ - spec/dummy/db/migrate/20130711061518_switch_publish_notification_process_state_from_boolean_to_string.hootenanny.rb
308
+ - spec/dummy/db/migrate/20130711061629_add_index_to_notifications_state.hootenanny.rb
202
309
  - spec/dummy/lib/assets/.gitkeep
203
310
  - spec/dummy/public/404.html
204
311
  - spec/dummy/public/422.html
205
312
  - spec/dummy/public/500.html
206
313
  - spec/dummy/public/favicon.ico
207
314
  - spec/dummy/script/rails
315
+ - spec/factories/publish_notification.rb
316
+ - spec/factories/requests/publish_notification.rb
317
+ - spec/factories/requests/subscription.rb
208
318
  - spec/factories/subscription.rb
319
+ - spec/factories/verification.rb
320
+ - spec/features/publishers/can_notify_the_hub_of_content_updates_spec.rb
321
+ - spec/features/subscribers/are_protected_from_unwarranted_subscriptions_spec.rb
322
+ - spec/features/subscribers/can_receive_distributions_of_topic_content_spec.rb
209
323
  - spec/features/subscribers/can_subscribe_to_a_topic_spec.rb
324
+ - spec/fixtures/feeds/atom/97d79220f68b4bf27.atom
325
+ - spec/fixtures/feeds/atom/sample_feed.atom
326
+ - spec/fixtures/feeds/digest/97d79220f68b4bf27.digest
327
+ - spec/fixtures/feeds/digest/complete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest
328
+ - spec/fixtures/feeds/digest/incomplete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest
329
+ - spec/fixtures/feeds/digest/sample_feed.digest
330
+ - spec/fixtures/feeds/json/97d79220f68b4bf27.json
331
+ - spec/fixtures/feeds/json/feed_with_one_item.json
332
+ - spec/fixtures/feeds/json/sample_feed.json
333
+ - spec/fixtures/feeds/rss/5b187098da59f077f/97d79220f68b4bf27.rss
334
+ - spec/fixtures/feeds/rss/97d79220f68b4bf27.rss
335
+ - spec/fixtures/feeds/rss/feed_with_one_item.rss
336
+ - spec/fixtures/feeds/rss/minimal_feed.rss
337
+ - spec/fixtures/feeds/rss/sample_feed.rss
338
+ - spec/fixtures/feeds/rss/sample_feed_2.rss
339
+ - spec/lib/hootenanny/configuration_spec.rb
340
+ - spec/lib/hootenanny/correspondent_spec.rb
341
+ - spec/lib/hootenanny/errors_spec.rb
342
+ - spec/lib/hootenanny/feed/atom_feed_item_spec.rb
343
+ - spec/lib/hootenanny/feed/atom_feed_spec.rb
344
+ - spec/lib/hootenanny/feed/digest_feed_item_spec.rb
345
+ - spec/lib/hootenanny/feed/digest_feed_spec.rb
346
+ - spec/lib/hootenanny/feed/feed_item_spec.rb
347
+ - spec/lib/hootenanny/feed/file_spec.rb
348
+ - spec/lib/hootenanny/feed/json_feed_item_spec.rb
349
+ - spec/lib/hootenanny/feed/json_feed_spec.rb
350
+ - spec/lib/hootenanny/feed/null_feed_spec.rb
351
+ - spec/lib/hootenanny/feed/rss_feed_item_spec.rb
352
+ - spec/lib/hootenanny/feed/rss_feed_spec.rb
353
+ - spec/lib/hootenanny/feed_spec.rb
354
+ - spec/lib/hootenanny/feed_store/file_feed_store_spec.rb
355
+ - spec/lib/hootenanny/feed_store/web_feed_store_spec.rb
356
+ - spec/lib/hootenanny/feed_store_spec.rb
357
+ - spec/lib/hootenanny/hub_spec.rb
358
+ - spec/lib/hootenanny/publish_notification_expiration_policy_spec.rb
359
+ - spec/lib/hootenanny/request/publish_notification_spec.rb
360
+ - spec/lib/hootenanny/request/subscription_spec.rb
361
+ - spec/lib/hootenanny/request_spec.rb
362
+ - spec/lib/hootenanny/subscription_delivery_spec.rb
363
+ - spec/lib/hootenanny/topic_spec.rb
364
+ - spec/lib/hootenanny/topic_synchronizer_spec.rb
365
+ - spec/lib/hootenanny/uri_spec.rb
366
+ - spec/lib/hootenanny/verification_spec.rb
367
+ - spec/models/hootenanny/publish_notification_spec.rb
210
368
  - spec/models/hootenanny/subscription_spec.rb
369
+ - spec/support/verification.rb
211
370
  homepage: https://github.com/thekompanee/hootenanny
212
371
  licenses: []
213
372
  post_install_message:
@@ -223,7 +382,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
382
  version: '0'
224
383
  segments:
225
384
  - 0
226
- hash: 3205946143954146130
385
+ hash: 3624011435823886776
227
386
  required_rubygems_version: !ruby/object:Gem::Requirement
228
387
  none: false
229
388
  requirements:
@@ -232,7 +391,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
391
  version: '0'
233
392
  segments:
234
393
  - 0
235
- hash: 3205946143954146130
394
+ hash: 3624011435823886776
236
395
  requirements: []
237
396
  rubyforge_project: hootenanny
238
397
  rubygems_version: 1.8.23
@@ -240,7 +399,6 @@ signing_key:
240
399
  specification_version: 3
241
400
  summary: PubSubHubBub Engine for Rails
242
401
  test_files:
243
- - spec/controllers/hootenanny/hub_spec.rb
244
402
  - spec/dummy/README.rdoc
245
403
  - spec/dummy/Rakefile
246
404
  - spec/dummy/app/assets/javascripts/application.js
@@ -271,12 +429,71 @@ test_files:
271
429
  - spec/dummy/db/migrate/20130522020714_rename_subscriptions_table.hootenanny.rb
272
430
  - spec/dummy/db/migrate/20130523000104_add_topic_to_subscriptions.hootenanny.rb
273
431
  - spec/dummy/db/migrate/20130523053741_add_subscriber_to_subscriptions.hootenanny.rb
432
+ - spec/dummy/db/migrate/20130607183149_add_started_at_and_lease_duration_to_subscriptions.hootenanny.rb
433
+ - spec/dummy/db/migrate/20130608231253_add_hmac_secret_to_subscription.hootenanny.rb
434
+ - spec/dummy/db/migrate/20130611235546_add_publish_notifications.hootenanny.rb
435
+ - spec/dummy/db/migrate/20130612153353_add_timestamps_to_publish_notification.hootenanny.rb
436
+ - spec/dummy/db/migrate/20130705200832_add_processed_flag_to_publish_notifications.hootenanny.rb
437
+ - spec/dummy/db/migrate/20130711061518_switch_publish_notification_process_state_from_boolean_to_string.hootenanny.rb
438
+ - spec/dummy/db/migrate/20130711061629_add_index_to_notifications_state.hootenanny.rb
274
439
  - spec/dummy/lib/assets/.gitkeep
275
440
  - spec/dummy/public/404.html
276
441
  - spec/dummy/public/422.html
277
442
  - spec/dummy/public/500.html
278
443
  - spec/dummy/public/favicon.ico
279
444
  - spec/dummy/script/rails
445
+ - spec/factories/publish_notification.rb
446
+ - spec/factories/requests/publish_notification.rb
447
+ - spec/factories/requests/subscription.rb
280
448
  - spec/factories/subscription.rb
449
+ - spec/factories/verification.rb
450
+ - spec/features/publishers/can_notify_the_hub_of_content_updates_spec.rb
451
+ - spec/features/subscribers/are_protected_from_unwarranted_subscriptions_spec.rb
452
+ - spec/features/subscribers/can_receive_distributions_of_topic_content_spec.rb
281
453
  - spec/features/subscribers/can_subscribe_to_a_topic_spec.rb
454
+ - spec/fixtures/feeds/atom/97d79220f68b4bf27.atom
455
+ - spec/fixtures/feeds/atom/sample_feed.atom
456
+ - spec/fixtures/feeds/digest/97d79220f68b4bf27.digest
457
+ - spec/fixtures/feeds/digest/complete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest
458
+ - spec/fixtures/feeds/digest/incomplete_broadcasted_items/5b187098da59f077f/97d79220f68b4bf27.digest
459
+ - spec/fixtures/feeds/digest/sample_feed.digest
460
+ - spec/fixtures/feeds/json/97d79220f68b4bf27.json
461
+ - spec/fixtures/feeds/json/feed_with_one_item.json
462
+ - spec/fixtures/feeds/json/sample_feed.json
463
+ - spec/fixtures/feeds/rss/5b187098da59f077f/97d79220f68b4bf27.rss
464
+ - spec/fixtures/feeds/rss/97d79220f68b4bf27.rss
465
+ - spec/fixtures/feeds/rss/feed_with_one_item.rss
466
+ - spec/fixtures/feeds/rss/minimal_feed.rss
467
+ - spec/fixtures/feeds/rss/sample_feed.rss
468
+ - spec/fixtures/feeds/rss/sample_feed_2.rss
469
+ - spec/lib/hootenanny/configuration_spec.rb
470
+ - spec/lib/hootenanny/correspondent_spec.rb
471
+ - spec/lib/hootenanny/errors_spec.rb
472
+ - spec/lib/hootenanny/feed/atom_feed_item_spec.rb
473
+ - spec/lib/hootenanny/feed/atom_feed_spec.rb
474
+ - spec/lib/hootenanny/feed/digest_feed_item_spec.rb
475
+ - spec/lib/hootenanny/feed/digest_feed_spec.rb
476
+ - spec/lib/hootenanny/feed/feed_item_spec.rb
477
+ - spec/lib/hootenanny/feed/file_spec.rb
478
+ - spec/lib/hootenanny/feed/json_feed_item_spec.rb
479
+ - spec/lib/hootenanny/feed/json_feed_spec.rb
480
+ - spec/lib/hootenanny/feed/null_feed_spec.rb
481
+ - spec/lib/hootenanny/feed/rss_feed_item_spec.rb
482
+ - spec/lib/hootenanny/feed/rss_feed_spec.rb
483
+ - spec/lib/hootenanny/feed_spec.rb
484
+ - spec/lib/hootenanny/feed_store/file_feed_store_spec.rb
485
+ - spec/lib/hootenanny/feed_store/web_feed_store_spec.rb
486
+ - spec/lib/hootenanny/feed_store_spec.rb
487
+ - spec/lib/hootenanny/hub_spec.rb
488
+ - spec/lib/hootenanny/publish_notification_expiration_policy_spec.rb
489
+ - spec/lib/hootenanny/request/publish_notification_spec.rb
490
+ - spec/lib/hootenanny/request/subscription_spec.rb
491
+ - spec/lib/hootenanny/request_spec.rb
492
+ - spec/lib/hootenanny/subscription_delivery_spec.rb
493
+ - spec/lib/hootenanny/topic_spec.rb
494
+ - spec/lib/hootenanny/topic_synchronizer_spec.rb
495
+ - spec/lib/hootenanny/uri_spec.rb
496
+ - spec/lib/hootenanny/verification_spec.rb
497
+ - spec/models/hootenanny/publish_notification_spec.rb
282
498
  - spec/models/hootenanny/subscription_spec.rb
499
+ - spec/support/verification.rb