pusher-fake 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pusher-fake.rb +4 -1
- data/lib/pusher-fake/channel.rb +9 -3
- data/lib/pusher-fake/channel/presence.rb +11 -9
- data/lib/pusher-fake/channel/private.rb +8 -5
- data/lib/pusher-fake/channel/public.rb +13 -14
- data/lib/pusher-fake/configuration.rb +2 -1
- data/lib/pusher-fake/connection.rb +41 -29
- data/lib/pusher-fake/cucumber.rb +2 -1
- data/lib/pusher-fake/server.rb +46 -45
- data/lib/pusher-fake/server/application.rb +89 -50
- data/lib/pusher-fake/support/base.rb +4 -9
- data/lib/pusher-fake/webhook.rb +3 -1
- data/spec/features/api/channels_spec.rb +7 -5
- data/spec/features/api/users_spec.rb +1 -1
- data/spec/features/client/event_spec.rb +6 -4
- data/spec/features/client/subscribe_spec.rb +8 -6
- data/spec/features/server/event_spec.rb +7 -7
- data/spec/features/server/webhooks_spec.rb +16 -4
- data/spec/lib/pusher-fake/channel/presence_spec.rb +57 -49
- data/spec/lib/pusher-fake/channel/private_spec.rb +42 -31
- data/spec/lib/pusher-fake/channel/public_spec.rb +37 -27
- data/spec/lib/pusher-fake/channel_spec.rb +51 -91
- data/spec/lib/pusher-fake/configuration_spec.rb +11 -5
- data/spec/lib/pusher-fake/connection_spec.rb +65 -39
- data/spec/lib/pusher-fake/server/application_spec.rb +219 -94
- data/spec/lib/pusher-fake/server_spec.rb +31 -41
- data/spec/lib/pusher-fake/webhook_spec.rb +29 -18
- data/spec/lib/pusher_fake_spec.rb +17 -15
- data/spec/support/application.rb +21 -19
- data/spec/support/application/public/javascripts/vendor/{pusher-3.1.0.js → pusher-3.2.1.js} +69 -48
- data/spec/support/application/views/index.erb +1 -1
- data/spec/support/capybara.rb +1 -3
- data/spec/support/helpers/connect.rb +1 -3
- data/spec/support/matchers/have_configuration_option.rb +2 -2
- data/spec/support/{pusher-fake.rb → pusher_fake.rb} +2 -1
- data/spec/support/webhooks.rb +5 -3
- metadata +38 -10
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe PusherFake::Channel::Private do
|
4
|
-
subject {
|
4
|
+
subject { described_class }
|
5
5
|
|
6
6
|
it "inherits from public channel" do
|
7
7
|
expect(subject.ancestors).to include(PusherFake::Channel::Public)
|
@@ -9,14 +9,14 @@ describe PusherFake::Channel::Private do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe PusherFake::Channel::Private, "#add" do
|
12
|
+
subject { described_class.new(name) }
|
13
|
+
|
12
14
|
let(:data) { { auth: authentication } }
|
13
15
|
let(:name) { "name" }
|
14
|
-
let(:connection) {
|
15
|
-
let(:connections) {
|
16
|
+
let(:connection) { instance_double(PusherFake::Connection, emit: nil) }
|
17
|
+
let(:connections) { instance_double(Array, push: nil, length: 0) }
|
16
18
|
let(:authentication) { "auth" }
|
17
19
|
|
18
|
-
subject { PusherFake::Channel::Private.new(name) }
|
19
|
-
|
20
20
|
before do
|
21
21
|
allow(PusherFake::Webhook).to receive(:trigger)
|
22
22
|
allow(subject).to receive(:connections).and_return(connections)
|
@@ -43,16 +43,18 @@ describe PusherFake::Channel::Private, "#add" do
|
|
43
43
|
|
44
44
|
subject.add(connection, data)
|
45
45
|
|
46
|
-
expect(connection).to have_received(:emit)
|
46
|
+
expect(connection).to have_received(:emit)
|
47
|
+
.with("pusher_internal:subscription_succeeded", {}, subject.name)
|
47
48
|
end
|
48
49
|
|
49
|
-
it "triggers
|
50
|
+
it "triggers occupied webhook for first connection added when authorized" do
|
50
51
|
allow(subject).to receive(:authorized?).and_return(true)
|
51
52
|
allow(subject).to receive(:connections).and_call_original
|
52
53
|
|
53
54
|
2.times { subject.add(connection, data) }
|
54
55
|
|
55
|
-
expect(PusherFake::Webhook).to have_received(:trigger)
|
56
|
+
expect(PusherFake::Webhook).to have_received(:trigger)
|
57
|
+
.with("channel_occupied", channel: name).once
|
56
58
|
end
|
57
59
|
|
58
60
|
it "unsuccessfully subscribes the connection when not authorized" do
|
@@ -60,7 +62,8 @@ describe PusherFake::Channel::Private, "#add" do
|
|
60
62
|
|
61
63
|
subject.add(connection, data)
|
62
64
|
|
63
|
-
expect(connection).to have_received(:emit)
|
65
|
+
expect(connection).to have_received(:emit)
|
66
|
+
.with("pusher_internal:subscription_error", {}, subject.name)
|
64
67
|
end
|
65
68
|
|
66
69
|
it "does not trigger channel occupied webhook when not authorized" do
|
@@ -69,19 +72,22 @@ describe PusherFake::Channel::Private, "#add" do
|
|
69
72
|
|
70
73
|
2.times { subject.add(connection, data) }
|
71
74
|
|
72
|
-
expect(PusherFake::Webhook).
|
75
|
+
expect(PusherFake::Webhook).not_to have_received(:trigger)
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
76
79
|
describe PusherFake::Channel::Private, "#authentication_for" do
|
77
|
-
|
78
|
-
let(:name) { "private-channel" }
|
79
|
-
let(:digest) { double(:digest) }
|
80
|
-
let(:string) { [id, name].join(":") }
|
81
|
-
let(:signature) { "signature" }
|
82
|
-
let(:configuration) { double(:configuration, key: "key", secret: "secret") }
|
80
|
+
subject { described_class.new(name) }
|
83
81
|
|
84
|
-
|
82
|
+
let(:id) { "1234" }
|
83
|
+
let(:name) { "private-channel" }
|
84
|
+
let(:digest) { instance_double(OpenSSL::Digest::SHA256) }
|
85
|
+
let(:string) { [id, name].join(":") }
|
86
|
+
let(:signature) { "signature" }
|
87
|
+
|
88
|
+
let(:configuration) do
|
89
|
+
instance_double(PusherFake::Configuration, key: "key", secret: "secret")
|
90
|
+
end
|
85
91
|
|
86
92
|
before do
|
87
93
|
allow(PusherFake).to receive(:configuration).and_return(configuration)
|
@@ -103,16 +109,20 @@ describe PusherFake::Channel::Private, "#authentication_for" do
|
|
103
109
|
end
|
104
110
|
end
|
105
111
|
|
106
|
-
describe PusherFake::Channel::Private,
|
107
|
-
|
108
|
-
|
109
|
-
let(:digest) { double(:digest) }
|
110
|
-
let(:string) { [id, name, channel_data].join(":") }
|
111
|
-
let(:signature) { "signature" }
|
112
|
-
let(:channel_data) { "{}" }
|
113
|
-
let(:configuration) { double(:configuration, key: "key", secret: "secret") }
|
112
|
+
describe PusherFake::Channel::Private,
|
113
|
+
"#authentication_for, with channel data" do
|
114
|
+
subject { described_class.new(name) }
|
114
115
|
|
115
|
-
|
116
|
+
let(:id) { "1234" }
|
117
|
+
let(:name) { "private-channel" }
|
118
|
+
let(:digest) { instance_double(OpenSSL::Digest::SHA256) }
|
119
|
+
let(:string) { [id, name, channel_data].join(":") }
|
120
|
+
let(:signature) { "signature" }
|
121
|
+
let(:channel_data) { "{}" }
|
122
|
+
|
123
|
+
let(:configuration) do
|
124
|
+
instance_double(PusherFake::Configuration, key: "key", secret: "secret")
|
125
|
+
end
|
116
126
|
|
117
127
|
before do
|
118
128
|
allow(PusherFake).to receive(:configuration).and_return(configuration)
|
@@ -135,14 +145,14 @@ describe PusherFake::Channel::Private, "#authentication_for, with channel data"
|
|
135
145
|
end
|
136
146
|
|
137
147
|
describe PusherFake::Channel::Private, "#authorized?" do
|
148
|
+
subject { described_class.new(name) }
|
149
|
+
|
138
150
|
let(:data) { { auth: authentication, channel_data: channel_data } }
|
139
151
|
let(:name) { "private-channel" }
|
140
|
-
let(:connection) {
|
152
|
+
let(:connection) { instance_double(PusherFake::Connection, id: "1") }
|
141
153
|
let(:channel_data) { "{}" }
|
142
154
|
let(:authentication) { "authentication" }
|
143
155
|
|
144
|
-
subject { PusherFake::Channel::Private.new(name) }
|
145
|
-
|
146
156
|
before do
|
147
157
|
allow(subject).to receive(:authentication_for)
|
148
158
|
end
|
@@ -150,7 +160,8 @@ describe PusherFake::Channel::Private, "#authorized?" do
|
|
150
160
|
it "generates authentication for the connection ID" do
|
151
161
|
subject.authorized?(connection, data)
|
152
162
|
|
153
|
-
expect(subject).to have_received(:authentication_for)
|
163
|
+
expect(subject).to have_received(:authentication_for)
|
164
|
+
.with(connection.id, channel_data)
|
154
165
|
end
|
155
166
|
|
156
167
|
it "returns true if the authentication matches" do
|
@@ -162,6 +173,6 @@ describe PusherFake::Channel::Private, "#authorized?" do
|
|
162
173
|
it "returns false if the authentication matches" do
|
163
174
|
allow(subject).to receive(:authentication_for).and_return("")
|
164
175
|
|
165
|
-
expect(subject).
|
176
|
+
expect(subject).not_to be_authorized(connection, data)
|
166
177
|
end
|
167
178
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe PusherFake::Channel::Public do
|
4
|
-
|
4
|
+
subject { described_class }
|
5
5
|
|
6
|
-
|
6
|
+
let(:name) { "channel" }
|
7
7
|
|
8
8
|
it "assigns the provided name" do
|
9
9
|
channel = subject.new(name)
|
@@ -19,12 +19,12 @@ describe PusherFake::Channel::Public do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
describe PusherFake::Channel, "#add" do
|
22
|
-
let(:name) { "name" }
|
23
|
-
let(:connection) { double(:connection, emit: nil) }
|
24
|
-
let(:connections) { double(:connections, push: nil, length: 0) }
|
25
|
-
|
26
22
|
subject { PusherFake::Channel::Public.new(name) }
|
27
23
|
|
24
|
+
let(:name) { "name" }
|
25
|
+
let(:connection) { instance_double(PusherFake::Connection, emit: nil) }
|
26
|
+
let(:connections) { instance_double(Array, push: nil, length: 0) }
|
27
|
+
|
28
28
|
before do
|
29
29
|
allow(PusherFake::Webhook).to receive(:trigger)
|
30
30
|
allow(subject).to receive(:connections).and_return(connections)
|
@@ -39,7 +39,8 @@ describe PusherFake::Channel, "#add" do
|
|
39
39
|
it "successfully subscribes the connection" do
|
40
40
|
subject.add(connection)
|
41
41
|
|
42
|
-
expect(connection).to have_received(:emit)
|
42
|
+
expect(connection).to have_received(:emit)
|
43
|
+
.with("pusher_internal:subscription_succeeded", {}, subject.name)
|
43
44
|
end
|
44
45
|
|
45
46
|
it "triggers channel occupied webhook for the first connection added" do
|
@@ -47,20 +48,27 @@ describe PusherFake::Channel, "#add" do
|
|
47
48
|
|
48
49
|
2.times { subject.add(connection) }
|
49
50
|
|
50
|
-
expect(PusherFake::Webhook).to have_received(:trigger)
|
51
|
+
expect(PusherFake::Webhook).to have_received(:trigger)
|
52
|
+
.with("channel_occupied", channel: name).once
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
56
|
describe PusherFake::Channel, "#emit" do
|
55
|
-
let(:data) { double }
|
56
|
-
let(:name) { "name" }
|
57
|
-
let(:event) { "event" }
|
58
|
-
let(:connections) { [connection_1, connection_2] }
|
59
|
-
let(:connection_1) { double(:connection, emit: nil, id: "1") }
|
60
|
-
let(:connection_2) { double(:connection, emit: nil, id: "2") }
|
61
|
-
|
62
57
|
subject { PusherFake::Channel::Public.new(name) }
|
63
58
|
|
59
|
+
let(:data) { double }
|
60
|
+
let(:name) { "name" }
|
61
|
+
let(:event) { "event" }
|
62
|
+
let(:connections) { [connection_1, connection_2] }
|
63
|
+
|
64
|
+
let(:connection_1) do
|
65
|
+
instance_double(PusherFake::Connection, emit: nil, id: "1")
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:connection_2) do
|
69
|
+
instance_double(PusherFake::Connection, emit: nil, id: "2")
|
70
|
+
end
|
71
|
+
|
64
72
|
before do
|
65
73
|
allow(subject).to receive(:connections).and_return(connections)
|
66
74
|
end
|
@@ -76,15 +84,15 @@ describe PusherFake::Channel, "#emit" do
|
|
76
84
|
subject.emit(event, data, socket_id: connection_2.id)
|
77
85
|
|
78
86
|
expect(connection_1).to have_received(:emit).with(event, data, name)
|
79
|
-
expect(connection_2).
|
87
|
+
expect(connection_2).not_to have_received(:emit)
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
83
91
|
describe PusherFake::Channel, "#includes?" do
|
84
|
-
let(:connection) { double }
|
85
|
-
|
86
92
|
subject { PusherFake::Channel::Public.new("name") }
|
87
93
|
|
94
|
+
let(:connection) { double }
|
95
|
+
|
88
96
|
it "returns true if the connection is in the channel" do
|
89
97
|
allow(subject).to receive(:connections).and_return([connection])
|
90
98
|
|
@@ -94,41 +102,43 @@ describe PusherFake::Channel, "#includes?" do
|
|
94
102
|
it "returns false if the connection is not in the channel" do
|
95
103
|
allow(subject).to receive(:connections).and_return([])
|
96
104
|
|
97
|
-
expect(subject).
|
105
|
+
expect(subject).not_to be_includes(connection)
|
98
106
|
end
|
99
107
|
end
|
100
108
|
|
101
109
|
describe PusherFake::Channel, "#remove" do
|
110
|
+
subject { PusherFake::Channel::Public.new(name) }
|
111
|
+
|
102
112
|
let(:name) { "name" }
|
103
|
-
let(:connection_1) { double
|
113
|
+
let(:connection_1) { double }
|
104
114
|
let(:connection_2) { double }
|
105
115
|
|
106
|
-
subject { PusherFake::Channel::Public.new(name) }
|
107
|
-
|
108
116
|
before do
|
109
|
-
allow(subject).to receive(:connections).and_return([connection_1, connection_2])
|
110
117
|
allow(PusherFake::Webhook).to receive(:trigger)
|
118
|
+
allow(subject).to receive(:connections)
|
119
|
+
.and_return([connection_1, connection_2])
|
111
120
|
end
|
112
121
|
|
113
122
|
it "removes the connection from the channel" do
|
114
123
|
subject.remove(connection_1)
|
115
124
|
|
116
|
-
expect(subject.connections).
|
125
|
+
expect(subject.connections).not_to include(connection_1)
|
117
126
|
end
|
118
127
|
|
119
128
|
it "triggers channel vacated webhook when all connections are removed" do
|
120
129
|
subject.remove(connection_1)
|
121
130
|
|
122
|
-
expect(PusherFake::Webhook).
|
131
|
+
expect(PusherFake::Webhook).not_to have_received(:trigger)
|
123
132
|
|
124
133
|
subject.remove(connection_2)
|
125
134
|
|
126
|
-
expect(PusherFake::Webhook).to have_received(:trigger)
|
135
|
+
expect(PusherFake::Webhook).to have_received(:trigger)
|
136
|
+
.with("channel_vacated", channel: name).once
|
127
137
|
end
|
128
138
|
end
|
129
139
|
|
130
140
|
describe PusherFake::Channel::Public, "#subscription_data" do
|
131
|
-
subject {
|
141
|
+
subject { described_class.new("name") }
|
132
142
|
|
133
143
|
it "returns an empty hash" do
|
134
144
|
expect(subject.subscription_data).to eq({})
|
@@ -1,120 +1,80 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe PusherFake::Channel, ".factory" do
|
4
|
-
|
5
|
-
|
4
|
+
shared_examples_for "a channel factory" do
|
5
|
+
subject { described_class }
|
6
6
|
|
7
|
-
|
7
|
+
let(:channel) { double }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
before do
|
10
|
+
allow(channel_class).to receive(:new).and_return(channel)
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
after do
|
14
|
+
subject.reset
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
it "caches the channel" do
|
18
|
+
allow(channel_class).to receive(:new).and_call_original
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
factory_one = subject.factory(name)
|
21
|
+
factory_two = subject.factory(name)
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
expect(factory_one).to eq(factory_two)
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
it "creates the channel by name" do
|
27
|
+
subject.factory(name)
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
expect(channel_class).to have_received(:new).with(name)
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
it "returns the channel instance" do
|
33
|
+
factory = subject.factory(name)
|
34
34
|
|
35
|
-
|
35
|
+
expect(factory).to eq(channel)
|
36
|
+
end
|
36
37
|
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe PusherFake::Channel, ".factory, for a private channel" do
|
40
|
-
let(:name) { "private-channel" }
|
41
|
-
let(:channel) { double }
|
42
38
|
|
43
|
-
|
39
|
+
context "for a public channel" do
|
40
|
+
let(:name) { "channel" }
|
41
|
+
let(:channel_class) { PusherFake::Channel::Public }
|
44
42
|
|
45
|
-
|
46
|
-
allow(PusherFake::Channel::Private).to receive(:new).and_return(channel)
|
43
|
+
it_behaves_like "a channel factory"
|
47
44
|
end
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
context "for a private channel" do
|
47
|
+
let(:name) { "private-channel" }
|
48
|
+
let(:channel_class) { PusherFake::Channel::Private }
|
52
49
|
|
53
|
-
|
54
|
-
allow(PusherFake::Channel::Private).to receive(:new).and_call_original
|
55
|
-
|
56
|
-
factory_1 = subject.factory(name)
|
57
|
-
factory_2 = subject.factory(name)
|
58
|
-
|
59
|
-
expect(factory_1).to eq(factory_2)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "creates a private channel by name" do
|
63
|
-
subject.factory(name)
|
64
|
-
|
65
|
-
expect(PusherFake::Channel::Private).to have_received(:new).with(name)
|
50
|
+
it_behaves_like "a channel factory"
|
66
51
|
end
|
67
52
|
|
68
|
-
|
69
|
-
|
53
|
+
context "for a presence channel" do
|
54
|
+
let(:name) { "presence-channel" }
|
55
|
+
let(:channel_class) { PusherFake::Channel::Presence }
|
70
56
|
|
71
|
-
|
57
|
+
it_behaves_like "a channel factory"
|
72
58
|
end
|
73
59
|
end
|
74
60
|
|
75
|
-
describe PusherFake::Channel, ".
|
76
|
-
|
77
|
-
let(:channel) { double }
|
78
|
-
|
79
|
-
subject { PusherFake::Channel }
|
80
|
-
|
81
|
-
before do
|
82
|
-
allow(PusherFake::Channel::Presence).to receive(:new).and_return(channel)
|
83
|
-
end
|
84
|
-
|
85
|
-
after do
|
86
|
-
PusherFake::Channel.reset
|
87
|
-
end
|
88
|
-
|
89
|
-
it "caches the channel" do
|
90
|
-
allow(PusherFake::Channel::Presence).to receive(:new).and_call_original
|
91
|
-
|
92
|
-
factory_1 = subject.factory(name)
|
93
|
-
factory_2 = subject.factory(name)
|
94
|
-
|
95
|
-
expect(factory_1).to eq(factory_2)
|
96
|
-
end
|
61
|
+
describe PusherFake::Channel, ".remove" do
|
62
|
+
subject { described_class }
|
97
63
|
|
98
|
-
|
99
|
-
|
64
|
+
let(:channels) { { channel_1: channel_1, channel_2: channel_2 } }
|
65
|
+
let(:connection) { double }
|
100
66
|
|
101
|
-
|
67
|
+
let(:channel_1) do
|
68
|
+
instance_double(PusherFake::Channel::Public,
|
69
|
+
remove: nil,
|
70
|
+
connections: instance_double(Array, empty?: true))
|
102
71
|
end
|
103
72
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
73
|
+
let(:channel_2) do
|
74
|
+
instance_double(PusherFake::Channel::Public,
|
75
|
+
remove: nil,
|
76
|
+
connections: instance_double(Array, empty?: false))
|
108
77
|
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe PusherFake::Channel, ".remove" do
|
112
|
-
let(:channels) { { channel_1: channel_1, channel_2: channel_2 } }
|
113
|
-
let(:channel_1) { double(:channel, connections: double(:array, empty?: true), remove: nil) }
|
114
|
-
let(:channel_2) { double(:channel, connections: double(:array, empty?: false), remove: nil) }
|
115
|
-
let(:connection) { double }
|
116
|
-
|
117
|
-
subject { PusherFake::Channel }
|
118
78
|
|
119
79
|
before do
|
120
80
|
allow(subject).to receive(:channels).and_return(channels)
|
@@ -130,7 +90,7 @@ describe PusherFake::Channel, ".remove" do
|
|
130
90
|
it "deletes a channel with no connections remaining" do
|
131
91
|
subject.remove(connection)
|
132
92
|
|
133
|
-
expect(channels).
|
93
|
+
expect(channels).not_to have_key(:channel_1)
|
134
94
|
end
|
135
95
|
|
136
96
|
it "does not delete a channel with connections remaining" do
|
@@ -142,14 +102,14 @@ describe PusherFake::Channel, ".remove" do
|
|
142
102
|
it "handles channels not being defined" do
|
143
103
|
allow(subject).to receive(:channels).and_return(nil)
|
144
104
|
|
145
|
-
expect
|
105
|
+
expect do
|
146
106
|
subject.remove(connection)
|
147
|
-
|
107
|
+
end.not_to raise_error
|
148
108
|
end
|
149
109
|
end
|
150
110
|
|
151
111
|
describe PusherFake::Channel, ".reset" do
|
152
|
-
subject {
|
112
|
+
subject { described_class }
|
153
113
|
|
154
114
|
it "empties the channel cache" do
|
155
115
|
subject.factory("example")
|