Skip to content

Commit 8eed3ee

Browse files
committed
Both support GET and POST HTTP requests for SSE subscription
1 parent c121848 commit 8eed3ee

File tree

4 files changed

+67
-19
lines changed

4 files changed

+67
-19
lines changed

neurow/integration_test/sse_livecycle_test.exs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule Neurow.IntegrationTest.SseLifecycleTest do
33

44
import SseHelper
55
import SseHelper.HttpSse
6+
import JwtHelper
67

78
alias Neurow.IntegrationTest.TestCluster
89

@@ -127,6 +128,30 @@ defmodule Neurow.IntegrationTest.SseLifecycleTest do
127128
end
128129
end
129130

131+
test "also supports GET HTTP requests for SSE subscription", %{
132+
cluster_state: %{
133+
public_api_ports: [first_public_port | _other_ports]
134+
}
135+
} do
136+
headers =
137+
[Authorization: "Bearer #{compute_jwt_token_in_req_header_public_api("test_topic")}"]
138+
139+
async_response = HTTPoison.get!(subscribe_url(first_public_port), headers, stream_to: self())
140+
141+
assert_receive %HTTPoison.AsyncStatus{code: 200}
142+
assert_receive %HTTPoison.AsyncHeaders{headers: headers}
143+
144+
assert_headers(headers, [
145+
{"access-control-allow-origin", "*"},
146+
{"cache-control", "no-cache, no-store"},
147+
{"connection", "close"},
148+
{"content-type", "text/event-stream"},
149+
{"transfer-encoding", "chunked"}
150+
])
151+
152+
:hackney.stop_async(async_response.id)
153+
end
154+
130155
def override_timeout(timeout) do
131156
{:ok, default_timeout} = Application.fetch_env(:neurow, :sse_timeout)
132157
TestCluster.update_sse_timeout(timeout)

neurow/lib/neurow/public_api/endpoint.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ defmodule Neurow.PublicApi.Endpoint do
2525
context_path = Neurow.Configuration.public_api_context_path()
2626

2727
case {conn.method, conn.request_path} do
28-
{"GET", ^context_path <> "/v1/subscribe"} ->
28+
{method, ^context_path <> "/v1/subscribe"} when method in ["GET", "POST"] ->
2929
subscribe(conn)
3030

3131
_ ->

neurow/test/neurow/public_api/endpoint_test.exs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule Neurow.PublicApi.EndpointTest do
99
describe "authentication" do
1010
test "denies access if no JWT token is provided" do
1111
conn =
12-
conn(:get, "/v1/subscribe")
12+
conn(:post, "/v1/subscribe")
1313

1414
call(Neurow.PublicApi.Endpoint, conn, fn ->
1515
assert_receive {:send_resp_status, 401}
@@ -33,7 +33,7 @@ defmodule Neurow.PublicApi.EndpointTest do
3333

3434
test "denies access if an invalid JWT token is provided" do
3535
conn =
36-
conn(:get, "/v1/subscribe")
36+
conn(:post, "/v1/subscribe")
3737
|> put_req_header("authorization", "Bearer bad_token")
3838

3939
call(Neurow.PublicApi.Endpoint, conn, fn ->
@@ -57,7 +57,7 @@ defmodule Neurow.PublicApi.EndpointTest do
5757

5858
test "allows access if a valid JWT token is provided" do
5959
conn =
60-
conn(:get, "/v1/subscribe")
60+
conn(:post, "/v1/subscribe")
6161
|> put_req_header(
6262
"authorization",
6363
"Bearer #{compute_jwt_token_in_req_header_public_api("foo56")}"
@@ -72,7 +72,7 @@ defmodule Neurow.PublicApi.EndpointTest do
7272
describe "messaging" do
7373
test "transmits messages for the subscribed topic" do
7474
conn =
75-
conn(:get, "/v1/subscribe")
75+
conn(:post, "/v1/subscribe")
7676
|> put_req_header(
7777
"authorization",
7878
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -113,7 +113,7 @@ defmodule Neurow.PublicApi.EndpointTest do
113113

114114
test "returns a bad request error if the Last-Event_Id header is not an integer" do
115115
conn =
116-
conn(:get, "/v1/subscribe")
116+
conn(:post, "/v1/subscribe")
117117
|> put_req_header(
118118
"authorization",
119119
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -152,7 +152,7 @@ defmodule Neurow.PublicApi.EndpointTest do
152152
publish_message("test_issuer1-test_topic1", 8, "Message ID8")
153153

154154
conn =
155-
conn(:get, "/v1/subscribe")
155+
conn(:post, "/v1/subscribe")
156156
|> put_req_header(
157157
"authorization",
158158
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -169,7 +169,7 @@ defmodule Neurow.PublicApi.EndpointTest do
169169
publish_message("test_issuer1-other_topic", 7, "This message is not expected")
170170

171171
conn =
172-
conn(:get, "/v1/subscribe")
172+
conn(:post, "/v1/subscribe")
173173
|> put_req_header(
174174
"authorization",
175175
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -194,7 +194,7 @@ defmodule Neurow.PublicApi.EndpointTest do
194194
publish_message("test_issuer1-test_topic1", 8, "Message ID8")
195195

196196
conn =
197-
conn(:get, "/v1/subscribe")
197+
conn(:post, "/v1/subscribe")
198198
|> put_req_header(
199199
"authorization",
200200
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -239,7 +239,7 @@ defmodule Neurow.PublicApi.EndpointTest do
239239
publish_message("test_issuer1-test_topic1", 8, "Message ID8")
240240

241241
conn =
242-
conn(:get, "/v1/subscribe")
242+
conn(:post, "/v1/subscribe")
243243
|> put_req_header(
244244
"authorization",
245245
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -263,7 +263,7 @@ defmodule Neurow.PublicApi.EndpointTest do
263263
publish_message("test_issuer1-test_topic1", 8, "Message ID8")
264264

265265
conn =
266-
conn(:get, "/v1/subscribe")
266+
conn(:post, "/v1/subscribe")
267267
|> put_req_header(
268268
"authorization",
269269
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -301,7 +301,7 @@ defmodule Neurow.PublicApi.EndpointTest do
301301
publish_message("test_issuer1-test_topic1", 8, "Message ID8")
302302

303303
conn =
304-
conn(:get, "/v1/subscribe")
304+
conn(:post, "/v1/subscribe")
305305
|> put_req_header(
306306
"authorization",
307307
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -341,7 +341,7 @@ defmodule Neurow.PublicApi.EndpointTest do
341341
override_timeout(500)
342342

343343
conn =
344-
conn(:get, "/v1/subscribe")
344+
conn(:post, "/v1/subscribe")
345345
|> put_req_header(
346346
"authorization",
347347
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -357,7 +357,7 @@ defmodule Neurow.PublicApi.EndpointTest do
357357
override_keepalive(500)
358358

359359
conn =
360-
conn(:get, "/v1/subscribe")
360+
conn(:post, "/v1/subscribe")
361361
|> put_req_header(
362362
"authorization",
363363
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -379,7 +379,7 @@ defmodule Neurow.PublicApi.EndpointTest do
379379

380380
test "the client is disconnected when the JWT token expires" do
381381
conn =
382-
conn(:get, "/v1/subscribe")
382+
conn(:post, "/v1/subscribe")
383383
|> put_req_header(
384384
"authorization",
385385
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1", duration_s: 3)}"
@@ -466,7 +466,7 @@ defmodule Neurow.PublicApi.EndpointTest do
466466

467467
test "the authentication logic is applied to urls prefixed by the context path" do
468468
conn =
469-
conn(:get, "/v1/subscribe")
469+
conn(:post, "/v1/subscribe")
470470

471471
call(Neurow.PublicApi.Endpoint, conn, fn ->
472472
assert_receive {:send_resp_status, 401}
@@ -490,7 +490,7 @@ defmodule Neurow.PublicApi.EndpointTest do
490490

491491
test "The subscribe url is prefixed with the context path" do
492492
conn =
493-
conn(:get, "/context_path/v1/subscribe")
493+
conn(:post, "/context_path/v1/subscribe")
494494
|> put_req_header(
495495
"authorization",
496496
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
@@ -511,6 +511,29 @@ defmodule Neurow.PublicApi.EndpointTest do
511511
end
512512
end
513513

514+
test "also support GET HTTP requests for SSE subscription" do
515+
conn =
516+
conn(:get, "/v1/subscribe")
517+
|> put_req_header(
518+
"authorization",
519+
"Bearer #{compute_jwt_token_in_req_header_public_api("test_topic1")}"
520+
)
521+
522+
call(Neurow.PublicApi.Endpoint, conn, fn ->
523+
assert_receive {:send_chunked, 200}
524+
525+
publish_message("test_issuer1-test_topic1", 1234, "Message")
526+
527+
assert_receive {:chunk, first_event}
528+
529+
assert parse_sse_event(first_event) == %{
530+
id: "1234",
531+
event: "test-event",
532+
data: "Message"
533+
}
534+
end)
535+
end
536+
514537
defp override_timeout(timeout) do
515538
default_timeout = Application.fetch_env!(:neurow, :sse_timeout)
516539
Application.put_env(:neurow, :sse_timeout, timeout)

neurow/test/sse_helper.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule SseHelper do
22
@moduledoc """
3-
Provides Helper function to test SSE connections
3+
Provides Helper functions to test SSE connections
44
- Functions at the root of the modules can be used both in unit and integration tests
55
- Functions in SseHelper.PlugSse help to test Plug endpoint in unit test,
66
- Functions in SSeHelper.HttpSse help to test Neurow though actual HTTP connections in integration tests
@@ -121,7 +121,7 @@ defmodule SseHelper do
121121
[Authorization: "Bearer #{compute_jwt_token_in_req_header_public_api(topic)}"] ++
122122
extra_headers
123123

124-
async_response = HTTPoison.get!(subscribe_url(port), headers, stream_to: self())
124+
async_response = HTTPoison.post!(subscribe_url(port), "", headers, stream_to: self())
125125
assert_fn.()
126126
:hackney.stop_async(async_response.id)
127127
end

0 commit comments

Comments
 (0)