contentful-webhook-listener 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -3
- data/CHANGELOG.md +4 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +55 -5
- data/contentful-webhook-listener.gemspec +2 -0
- data/lib/contentful/webhook/listener.rb +1 -0
- data/lib/contentful/webhook/listener/controllers.rb +1 -0
- data/lib/contentful/webhook/listener/controllers/base.rb +1 -1
- data/lib/contentful/webhook/listener/controllers/wait.rb +1 -0
- data/lib/contentful/webhook/listener/controllers/webhook_aware.rb +50 -0
- data/lib/contentful/webhook/listener/support/null_logger.rb +3 -1
- data/lib/contentful/webhook/listener/version.rb +1 -1
- data/lib/contentful/webhook/listener/webhooks.rb +80 -0
- data/spec/contentful/webhook/listener/controllers/wait_spec.rb +1 -17
- data/spec/contentful/webhook/listener/controllers/webhook_aware_spec.rb +26 -0
- data/spec/contentful/webhook/listener/webhooks_spec.rb +142 -0
- data/spec/spec_helper.rb +35 -1
- metadata +38 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ead87c79c6faa39c84983c279db131c1968c03ae
|
4
|
+
data.tar.gz: 78d9920ce209f081d38328df7d36d6f199981746
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e5111ccd3751dda799a590371247f919933d2aed6f4604fe5bd459f54582825b40a78e23a25240f3a424a574fa6296cd6662c5d824b6d8ac8b0e0e31b0f68e4
|
7
|
+
data.tar.gz: ff31507c823c30180b93ad98fe4cd2985f4ba44fb956acd6d73a33c8438765d83c885ae9622f444c5f410a862c97eed7e5d05a1992cdcd069f8e28d313b3ab34
|
data/.travis.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
rvm:
|
2
|
-
- 1.9.3
|
3
2
|
- 2.0.0
|
4
|
-
-
|
5
|
-
|
3
|
+
- 2.1.0
|
4
|
+
- 2.2.3
|
5
|
+
- 2.3.0
|
6
6
|
env: TEST=true
|
7
|
+
notifications:
|
8
|
+
slack:
|
9
|
+
secure: SJn1oaxNBtYfT3vDMY82Q4l8m2QlDfiLGwY4/N+5RNdw5u03ebAjoiuGrzcbWGRxt7eiFQjH/EyApq4f1WkB1jARdOg7I45IOIH1PEcks2U5PEqtRidNR/7ySm8UjAkDnXviZPhhBaUOCgQNNIl4zvLUnGKAJYTUvub2owWkGzT1pamewFq4JznPPpdzHW3BcAk/lo5a+vvLTIIeHwwYfcsRZYf+C3Q/Ii+S8RgXn8uAQ+TIv2uRR3o/whnnGXPghEUkBraS+KAdd46k9iEuL1D2DvogwGbPg0Rvd+g3LzpIKhVAvV1lIPiwBDXGeUYGgM5b2GcPVbpI/ktEeHKokIdKn9LpBQ1d63KQ2Sx23ggP2mXoF+0UIDZWiS9mG7UYyrf2YAps8/EPvist1AIJuu9UCs7Wxi+r3MaeBM/CM5vMLToTq3uWaBtbctIQl8DUslnC6m1kL4vPwKureMYQX1DssIZ5kyOkHNEHwKdre3j7R/9tWdWOgPotozACUNovOHh9a3DZusYZcFx+H56/SKIEnD50TNY3DguJbNwEdGHqhwQ/aql04qg/4jXfT5hnPNqLVzq+T+wu85t53CQP/+0PP/Rt7JZo9/CE9n1jEF7UrQbJRuyBCqkJU5+mkjVYM3wVgs9m1TFG+Y6sJyBrMd+W5aG0BM1QZ7QofX/pQN0=
|
data/CHANGELOG.md
CHANGED
data/Guardfile
ADDED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -30,24 +30,23 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
## Usage
|
32
32
|
|
33
|
-
Require gem:
|
33
|
+
* Require gem:
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
require 'contentful/webhook/listener'
|
37
37
|
```
|
38
38
|
|
39
|
-
Create your own Controllers:
|
39
|
+
* Create your own Controllers:
|
40
40
|
|
41
41
|
```ruby
|
42
|
-
class MyController < Contentful::Webhook::Listener::Controllers::
|
42
|
+
class MyController < Contentful::Webhook::Listener::Controllers::Base
|
43
43
|
def perform(request, response)
|
44
|
-
super(request, response)
|
45
44
|
"do your process..." # This will run on a brackground Thread
|
46
45
|
end
|
47
46
|
end
|
48
47
|
```
|
49
48
|
|
50
|
-
Configure and start your Webhook Listener
|
49
|
+
* Configure and start your Webhook Listener
|
51
50
|
|
52
51
|
```ruby
|
53
52
|
require 'logger'
|
@@ -68,6 +67,57 @@ end
|
|
68
67
|
|
69
68
|
You can add multiple endpoints, each with it's own Controller.
|
70
69
|
|
70
|
+
### Webhook Aware Controllers
|
71
|
+
|
72
|
+
You can create controllers that can respond on specific Webhook events.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class MyController < Contentful::Webhook::Listener::Controllers::WebhookAware
|
76
|
+
def publish
|
77
|
+
# Do stuff on publish
|
78
|
+
if webhook.entry?
|
79
|
+
logger.info "published Entry ID: #{webhook.id} for Space: #{webhook.space_id}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def unpublish
|
84
|
+
# Do stuff on unpublish
|
85
|
+
end
|
86
|
+
|
87
|
+
def archive
|
88
|
+
# Do stuff on archive
|
89
|
+
end
|
90
|
+
|
91
|
+
def unarchive
|
92
|
+
# Do stuff on unarchive
|
93
|
+
end
|
94
|
+
|
95
|
+
def create
|
96
|
+
# Do stuff on create
|
97
|
+
end
|
98
|
+
|
99
|
+
def save
|
100
|
+
# Do stuff on save
|
101
|
+
end
|
102
|
+
|
103
|
+
def delete
|
104
|
+
# Do stuff on delete
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
The controller has a `webhook` object bound when invoked, that has a few helpers:
|
110
|
+
|
111
|
+
* `webhook.entry?` will return if the webhook was fired for an Entry
|
112
|
+
* `webhook.asset?` will return if the webhook was fired for an Asset
|
113
|
+
* `webhook.content_type?` will return if the webhook was fired for a Content Type
|
114
|
+
|
115
|
+
* `webhook.id` will return the Resource (Entry/Asset/Content Type) ID
|
116
|
+
* `webhook.space_id` will return the Space ID
|
117
|
+
|
118
|
+
* `webhook.sys` will include the metadata for the resource
|
119
|
+
* `webhook.fields` will include the resource fields (not included on Unpublish)
|
120
|
+
|
71
121
|
## Contributing
|
72
122
|
|
73
123
|
1. Fork it ( https://github.com/[my-github-username]/contentful-webhook-listener/fork )
|
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "guard"
|
25
|
+
spec.add_development_dependency "guard-rspec"
|
24
26
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'contentful/webhook/listener/controllers/wait'
|
2
|
+
require 'contentful/webhook/listener/webhooks'
|
3
|
+
|
4
|
+
module Contentful
|
5
|
+
module Webhook
|
6
|
+
module Listener
|
7
|
+
module Controllers
|
8
|
+
class WebhookAware < Wait
|
9
|
+
attr_reader :webhook
|
10
|
+
|
11
|
+
def publish
|
12
|
+
end
|
13
|
+
|
14
|
+
def unpublish
|
15
|
+
end
|
16
|
+
|
17
|
+
def archive
|
18
|
+
end
|
19
|
+
|
20
|
+
def unarchive
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
end
|
25
|
+
|
26
|
+
def auto_save
|
27
|
+
end
|
28
|
+
|
29
|
+
def create
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def perform(request, response)
|
38
|
+
@webhook = WebhookFactory.new(request).create
|
39
|
+
super(request, response)
|
40
|
+
logger.debug "Webhook Data: {id: #{webhook.id}, space_id: #{webhook.space_id}, kind: #{webhook.kind}, event: #{webhook.event}}"
|
41
|
+
send(webhook.event)
|
42
|
+
rescue
|
43
|
+
response.body = "Not a Webhook"
|
44
|
+
response.status = 400
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -4,7 +4,7 @@ module Contentful
|
|
4
4
|
module Support
|
5
5
|
# NullLogger will silence any call to the :logger instance
|
6
6
|
class NullLogger
|
7
|
-
def write(
|
7
|
+
def write(*)
|
8
8
|
nil
|
9
9
|
end
|
10
10
|
|
@@ -12,6 +12,8 @@ module Contentful
|
|
12
12
|
alias_method :debug, :write
|
13
13
|
alias_method :warn, :write
|
14
14
|
alias_method :error, :write
|
15
|
+
alias_method :fatal, :write
|
16
|
+
alias_method :debug?, :write
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Contentful
|
4
|
+
module Webhook
|
5
|
+
module Listener
|
6
|
+
module WebhookConstants
|
7
|
+
WEBHOOK_TOPIC = 'X-Contentful-Topic'
|
8
|
+
WEBHOOK_NAME = 'X-Contentful-Webhook-Name'
|
9
|
+
end
|
10
|
+
|
11
|
+
class WebhookFactory
|
12
|
+
def initialize(request)
|
13
|
+
@headers = {}
|
14
|
+
request.each { |header, value| @headers[header] = value }
|
15
|
+
@body = JSON.load(request.body)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
webhook_class.new(@headers, @body)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def webhook_class
|
25
|
+
Object.const_get(webhook_class_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def webhook_class_name
|
29
|
+
event_name = @headers[::Contentful::Webhook::Listener::WebhookConstants::WEBHOOK_TOPIC].split('.')[-1].split('_').collect(&:capitalize).join
|
30
|
+
"Contentful::Webhook::Listener::#{event_name}Webhook"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class BaseWebhook
|
35
|
+
attr_reader :origin, :kind, :event, :raw_topic, :raw_headers, :raw_body, :id, :name, :space_id, :sys
|
36
|
+
|
37
|
+
def initialize(headers, body)
|
38
|
+
@raw_topic = headers[::Contentful::Webhook::Listener::WebhookConstants::WEBHOOK_TOPIC]
|
39
|
+
@name = headers[::Contentful::Webhook::Listener::WebhookConstants::WEBHOOK_NAME]
|
40
|
+
@origin, @kind, @event = @raw_topic.split('.')
|
41
|
+
@raw_body = body
|
42
|
+
@raw_headers = headers
|
43
|
+
@sys = body['sys']
|
44
|
+
@id = sys['id']
|
45
|
+
@space_id = sys['space']['sys']['id']
|
46
|
+
end
|
47
|
+
|
48
|
+
def entry?
|
49
|
+
kind == 'Entry'
|
50
|
+
end
|
51
|
+
|
52
|
+
def asset?
|
53
|
+
kind == 'Asset'
|
54
|
+
end
|
55
|
+
|
56
|
+
def content_type?
|
57
|
+
kind == 'ContentType'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class FieldWebhook < BaseWebhook
|
62
|
+
attr_reader :fields
|
63
|
+
|
64
|
+
def initialize(headers, body)
|
65
|
+
super(headers, body)
|
66
|
+
@fields = body['fields']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class PublishWebhook < FieldWebhook; end
|
71
|
+
class SaveWebhook < FieldWebhook; end
|
72
|
+
class AutoSaveWebhook < FieldWebhook; end
|
73
|
+
class CreateWebhook < FieldWebhook; end
|
74
|
+
class ArchiveWebhook < FieldWebhook; end
|
75
|
+
class UnarchiveWebhook < FieldWebhook; end
|
76
|
+
class UnpublishWebhook < BaseWebhook; end
|
77
|
+
class DeleteWebhook < BaseWebhook; end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,19 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class Contentful::Webhook::Listener::Controllers::Wait
|
4
|
-
@@sleeping = false
|
5
|
-
|
6
|
-
def sleep(time)
|
7
|
-
@@sleeping = true
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.sleeping
|
11
|
-
value = @@sleeping
|
12
|
-
@@sleeping = false
|
13
|
-
value
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
3
|
describe Contentful::Webhook::Listener::Controllers::Wait do
|
18
4
|
let(:server) { MockServer.new }
|
19
5
|
let(:logger) { Contentful::Webhook::Listener::Support::NullLogger.new }
|
@@ -31,9 +17,7 @@ describe Contentful::Webhook::Listener::Controllers::Wait do
|
|
31
17
|
# This spec requires to read/erase a Class Variable
|
32
18
|
# because RSpec doesn't know how to test within spawned Threads
|
33
19
|
it "##{name} wait on background" do
|
34
|
-
wait.send(name, MockRequest.new, MockResponse.new)
|
35
|
-
|
36
|
-
sleep(0.1) # Wait for Thread to actually run
|
20
|
+
wait.send(name, MockRequest.new, MockResponse.new).join
|
37
21
|
|
38
22
|
expect(wait.class.sleeping).to be_truthy
|
39
23
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Contentful::Webhook::Listener::Controllers::WebhookAware do
|
4
|
+
let(:server) { MockServer.new }
|
5
|
+
let(:logger) { Contentful::Webhook::Listener::Support::NullLogger.new }
|
6
|
+
let(:timeout) { 10 }
|
7
|
+
let(:body) { {sys: { id: 'foo', space: { sys: { id: 'space_foo' } } }, fields: {} } }
|
8
|
+
subject { described_class.new(server, logger, timeout) }
|
9
|
+
|
10
|
+
describe 'event methods called for corresponding webhook event type' do
|
11
|
+
[:publish, :unpublish, :archive, :unarchive, :save, :auto_save, :create, :delete].each do |event|
|
12
|
+
it "calls ##{event}" do
|
13
|
+
expect(subject).to receive(event)
|
14
|
+
subject.respond(RequestDummy.new({'X-Contentful-Topic' => "ContentfulManagement.Entry.#{event}"}, body), MockResponse.new).join
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns 400 Bad Request on non-webhook call' do
|
20
|
+
response = MockResponse.new
|
21
|
+
subject.respond(RequestDummy.new(nil, "foo"), response).join
|
22
|
+
|
23
|
+
expect(response.status).to eq(400)
|
24
|
+
expect(response.body).to eq('Not a Webhook')
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Contentful::Webhook::Listener::WebhookFactory do
|
4
|
+
let(:body) { {sys: { id: 'foo', space: { sys: { id: 'space_foo' } } }, fields: {} } }
|
5
|
+
let(:topic) { 'ContentfulManagement.Entry.publish' }
|
6
|
+
let(:name) { 'WebhookName' }
|
7
|
+
let(:request) { RequestDummy.new({'X-Contentful-Topic' => topic, 'X-Contentful-Webhook-Name' => name}, body) }
|
8
|
+
subject { described_class.new(request) }
|
9
|
+
|
10
|
+
|
11
|
+
describe 'instance methods' do
|
12
|
+
describe '#create' do
|
13
|
+
describe 'retrieves an instance of the correct webhook type' do
|
14
|
+
it 'publish event creates a PublishWebhook' do
|
15
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.publish'}, body)).create
|
16
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::PublishWebhook
|
17
|
+
end
|
18
|
+
it 'save event creates a SaveWebhook' do
|
19
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.save'}, body)).create
|
20
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::SaveWebhook
|
21
|
+
end
|
22
|
+
it 'auto_save event creates an AutoSaveWebhook' do
|
23
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.auto_save'}, body)).create
|
24
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::AutoSaveWebhook
|
25
|
+
end
|
26
|
+
it 'create event creates a CreateWebhook' do
|
27
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.create'}, body)).create
|
28
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::CreateWebhook
|
29
|
+
end
|
30
|
+
it 'archive event creates a ArchiveWebhook' do
|
31
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.archive'}, body)).create
|
32
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::ArchiveWebhook
|
33
|
+
end
|
34
|
+
it 'unarchive event creates a UnarchiveWebhook' do
|
35
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.unarchive'}, body)).create
|
36
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::UnarchiveWebhook
|
37
|
+
end
|
38
|
+
it 'unpublish event creates a UnpublishWebhook' do
|
39
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.unpublish'}, body)).create
|
40
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::UnpublishWebhook
|
41
|
+
end
|
42
|
+
it 'delete event creates a DeleteWebhook' do
|
43
|
+
webhook = described_class.new(RequestDummy.new({'X-Contentful-Topic' => 'ContentfulManagement.Entry.delete'}, body)).create
|
44
|
+
expect(webhook).to be_a Contentful::Webhook::Listener::DeleteWebhook
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe Contentful::Webhook::Listener::BaseWebhook do
|
52
|
+
let(:body) { {'sys' => { 'id' => 'foo', 'space' => { 'sys' => { 'id' => 'space_foo' } } }, 'fields' => {} } }
|
53
|
+
let(:topic) { 'ContentfulManagement.Entry.publish' }
|
54
|
+
let(:name) { 'WebhookName' }
|
55
|
+
let(:headers) { {'X-Contentful-Topic' => topic, 'X-Contentful-Webhook-Name' => name} }
|
56
|
+
subject { described_class.new(headers, body) }
|
57
|
+
|
58
|
+
describe 'attributes' do
|
59
|
+
it ':origin' do
|
60
|
+
expect(subject.origin).to eq 'ContentfulManagement'
|
61
|
+
end
|
62
|
+
it ':kind' do
|
63
|
+
expect(subject.kind).to eq 'Entry'
|
64
|
+
end
|
65
|
+
it ':event' do
|
66
|
+
expect(subject.event).to eq 'publish'
|
67
|
+
end
|
68
|
+
it ':raw_topic' do
|
69
|
+
expect(subject.raw_topic).to eq 'ContentfulManagement.Entry.publish'
|
70
|
+
end
|
71
|
+
it ':raw_body' do
|
72
|
+
expect(subject.raw_body).to eq body
|
73
|
+
end
|
74
|
+
it ':id' do
|
75
|
+
expect(subject.id).to eq 'foo'
|
76
|
+
end
|
77
|
+
it ':name' do
|
78
|
+
expect(subject.name).to eq 'WebhookName'
|
79
|
+
end
|
80
|
+
it ':space_id' do
|
81
|
+
expect(subject.space_id).to eq 'space_foo'
|
82
|
+
end
|
83
|
+
it ':sys' do
|
84
|
+
expect(subject.sys).to eq body['sys']
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'instance methods' do
|
89
|
+
describe 'kind methods' do
|
90
|
+
describe '#entry?' do
|
91
|
+
it 'true when kind == Entry' do
|
92
|
+
expect(described_class.new(headers, body).entry?).to be_truthy
|
93
|
+
end
|
94
|
+
it 'false when kind != Entry' do
|
95
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.Asset.publish'
|
96
|
+
expect(described_class.new(headers, body).entry?).to be_falsey
|
97
|
+
|
98
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.ContentType.publish'
|
99
|
+
expect(described_class.new(headers, body).entry?).to be_falsey
|
100
|
+
end
|
101
|
+
end
|
102
|
+
describe '#asset?' do
|
103
|
+
it 'true when kind == Asset' do
|
104
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.Asset.publish'
|
105
|
+
expect(described_class.new(headers, body).asset?).to be_truthy
|
106
|
+
end
|
107
|
+
it 'false when kind != Asset' do
|
108
|
+
expect(described_class.new(headers, body).asset?).to be_falsey
|
109
|
+
|
110
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.ContentType.publish'
|
111
|
+
expect(described_class.new(headers, body).asset?).to be_falsey
|
112
|
+
end
|
113
|
+
end
|
114
|
+
describe '#content_type?' do
|
115
|
+
it 'true when kind == ContentType' do
|
116
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.ContentType.publish'
|
117
|
+
expect(described_class.new(headers, body).content_type?).to be_truthy
|
118
|
+
end
|
119
|
+
it 'false when kind != ContentType' do
|
120
|
+
expect(described_class.new(headers, body).content_type?).to be_falsey
|
121
|
+
|
122
|
+
headers['X-Contentful-Topic'] = 'ContentfulManagement.Asset.publish'
|
123
|
+
expect(described_class.new(headers, body).content_type?).to be_falsey
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe Contentful::Webhook::Listener::FieldWebhook do
|
131
|
+
let(:body) { {'sys' => { 'id' => 'foo', 'space' => { 'sys' => { 'id' => 'space_foo' } } }, 'fields' => {} } }
|
132
|
+
let(:topic) { 'ContentfulManagement.Entry.publish' }
|
133
|
+
let(:name) { 'WebhookName' }
|
134
|
+
let(:headers) { {'X-Contentful-Topic' => topic, 'X-Contentful-Webhook-Name' => name} }
|
135
|
+
subject { described_class.new(headers, body) }
|
136
|
+
|
137
|
+
describe 'attributes' do
|
138
|
+
it ':fields' do
|
139
|
+
expect(subject.fields).to eq body['fields']
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
$LOAD_PATH.unshift File.expand_path('lib', __FILE__)
|
2
2
|
|
3
|
-
require 'contentful/webhook/listener'
|
4
3
|
require 'rspec'
|
5
4
|
require 'rspec/mocks'
|
5
|
+
require 'contentful/webhook/listener'
|
6
|
+
require 'json'
|
6
7
|
|
7
8
|
class MockServer
|
8
9
|
def [](key)
|
@@ -16,3 +17,36 @@ end
|
|
16
17
|
class MockResponse
|
17
18
|
attr_accessor :status, :body
|
18
19
|
end
|
20
|
+
|
21
|
+
class RequestDummy
|
22
|
+
attr_reader :headers, :body
|
23
|
+
|
24
|
+
def initialize(headers, body)
|
25
|
+
@headers = headers || {}
|
26
|
+
@body = JSON.dump(body)
|
27
|
+
end
|
28
|
+
|
29
|
+
def [](key)
|
30
|
+
headers[key]
|
31
|
+
end
|
32
|
+
|
33
|
+
def each
|
34
|
+
headers.each do |h, v|
|
35
|
+
yield(h, v)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Contentful::Webhook::Listener::Controllers::Wait
|
41
|
+
@@sleeping = false
|
42
|
+
|
43
|
+
def sleep(time)
|
44
|
+
@@sleeping = true
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.sleeping
|
48
|
+
value = @@sleeping
|
49
|
+
@@sleeping = false
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contentful-webhook-listener
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Contentful GmbH (David Litvak Bruno)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: A Simple HTTP Webserver with pluggable behavior for listening to Contentful
|
56
84
|
API Webhooks
|
57
85
|
email:
|
@@ -65,6 +93,7 @@ files:
|
|
65
93
|
- CHANGELOG.md
|
66
94
|
- CONTRIBUTING.md
|
67
95
|
- Gemfile
|
96
|
+
- Guardfile
|
68
97
|
- LICENSE
|
69
98
|
- LICENSE.txt
|
70
99
|
- README.md
|
@@ -74,14 +103,18 @@ files:
|
|
74
103
|
- lib/contentful/webhook/listener/controllers.rb
|
75
104
|
- lib/contentful/webhook/listener/controllers/base.rb
|
76
105
|
- lib/contentful/webhook/listener/controllers/wait.rb
|
106
|
+
- lib/contentful/webhook/listener/controllers/webhook_aware.rb
|
77
107
|
- lib/contentful/webhook/listener/server.rb
|
78
108
|
- lib/contentful/webhook/listener/support.rb
|
79
109
|
- lib/contentful/webhook/listener/support/null_logger.rb
|
80
110
|
- lib/contentful/webhook/listener/version.rb
|
111
|
+
- lib/contentful/webhook/listener/webhooks.rb
|
81
112
|
- spec/contentful/webhook/listener/controllers/base_spec.rb
|
82
113
|
- spec/contentful/webhook/listener/controllers/wait_spec.rb
|
114
|
+
- spec/contentful/webhook/listener/controllers/webhook_aware_spec.rb
|
83
115
|
- spec/contentful/webhook/listener/server_spec.rb
|
84
116
|
- spec/contentful/webhook/listener/support/null_logger_spec.rb
|
117
|
+
- spec/contentful/webhook/listener/webhooks_spec.rb
|
85
118
|
- spec/spec_helper.rb
|
86
119
|
homepage: https://github.com/contentful/contentful-webhook-listener.rb
|
87
120
|
licenses:
|
@@ -103,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
136
|
version: '0'
|
104
137
|
requirements: []
|
105
138
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
139
|
+
rubygems_version: 2.5.0
|
107
140
|
signing_key:
|
108
141
|
specification_version: 4
|
109
142
|
summary: A Simple HTTP Webserver with pluggable behavior for listening to Contentful
|
@@ -111,6 +144,8 @@ summary: A Simple HTTP Webserver with pluggable behavior for listening to Conten
|
|
111
144
|
test_files:
|
112
145
|
- spec/contentful/webhook/listener/controllers/base_spec.rb
|
113
146
|
- spec/contentful/webhook/listener/controllers/wait_spec.rb
|
147
|
+
- spec/contentful/webhook/listener/controllers/webhook_aware_spec.rb
|
114
148
|
- spec/contentful/webhook/listener/server_spec.rb
|
115
149
|
- spec/contentful/webhook/listener/support/null_logger_spec.rb
|
150
|
+
- spec/contentful/webhook/listener/webhooks_spec.rb
|
116
151
|
- spec/spec_helper.rb
|