blob: bf5cee315e6c65bd0676aea1cdb7316f99e91489 [file] [log] [blame]
Ed Tanous8f79c5b2024-01-30 15:56:37 -08001#include "http/server_sent_event.hpp"
Ed Tanous41fe81c2024-09-02 15:08:41 -07002#include "http_request.hpp"
Ed Tanous8f79c5b2024-01-30 15:56:37 -08003
Ed Tanousf0b59af2024-03-20 13:38:04 -07004#include <boost/asio/buffer.hpp>
5#include <boost/asio/io_context.hpp>
Ed Tanous8d45b9c2024-04-08 17:50:10 -07006#include <boost/asio/read.hpp>
Ed Tanous8f79c5b2024-01-30 15:56:37 -08007#include <boost/beast/_experimental/test/stream.hpp>
8
Ed Tanousf0b59af2024-03-20 13:38:04 -07009#include <chrono>
Ed Tanous8f79c5b2024-01-30 15:56:37 -080010#include <memory>
11#include <string>
12#include <string_view>
Ed Tanousf0b59af2024-03-20 13:38:04 -070013#include <utility>
Ed Tanous8f79c5b2024-01-30 15:56:37 -080014
15#include "gtest/gtest.h"
16namespace crow
17{
18namespace sse_socket
19{
20
21namespace
22{
23
24TEST(ServerSentEvent, SseWorks)
25{
26 boost::asio::io_context io;
27 boost::beast::test::stream stream(io);
28 boost::beast::test::stream out(io);
29 stream.connect(out);
30
Ed Tanousf80a87f2024-06-16 12:10:33 -070031 Request req;
32
Ed Tanous8f79c5b2024-01-30 15:56:37 -080033 bool openCalled = false;
Patrick Williamsbd79bce2024-08-16 15:22:20 -040034 auto openHandler =
35 [&openCalled](Connection&, const Request& /*handedReq*/) {
36 openCalled = true;
37 };
Ed Tanous8f79c5b2024-01-30 15:56:37 -080038 bool closeCalled = false;
39 auto closeHandler = [&closeCalled](Connection&) { closeCalled = true; };
40
41 std::shared_ptr<ConnectionImpl<boost::beast::test::stream>> conn =
42 std::make_shared<ConnectionImpl<boost::beast::test::stream>>(
Ed Tanous93cf0ac2024-03-28 00:35:13 -070043 std::move(stream), openHandler, closeHandler);
Ed Tanousf80a87f2024-06-16 12:10:33 -070044 conn->start(req);
Ed Tanous8f79c5b2024-01-30 15:56:37 -080045 // Connect
46 {
47 constexpr std::string_view expected =
48 "HTTP/1.1 200 OK\r\n"
49 "Content-Type: text/event-stream\r\n"
50 "\r\n";
51
52 while (out.str().size() != expected.size())
53 {
54 io.run_for(std::chrono::milliseconds(1));
55 }
56
57 std::string eventContent;
58 eventContent.resize(expected.size());
59 boost::asio::read(out, boost::asio::buffer(eventContent));
60
61 EXPECT_EQ(eventContent, expected);
62 EXPECT_TRUE(openCalled);
63 EXPECT_FALSE(closeCalled);
64 EXPECT_TRUE(out.str().empty());
65 }
66 // Send one event
67 {
Ed Tanous6d799e12024-09-11 14:33:37 -070068 conn->sendSseEvent("TestEventId", "TestEventContent");
Ed Tanous8f79c5b2024-01-30 15:56:37 -080069 std::string_view expected = "id: TestEventId\n"
70 "data: TestEventContent\n"
71 "\n";
72
73 while (out.str().size() < expected.size())
74 {
75 io.run_for(std::chrono::milliseconds(1));
76 }
77 EXPECT_EQ(out.str(), expected);
78
79 std::string eventContent;
80 eventContent.resize(expected.size());
81 boost::asio::read(out, boost::asio::buffer(eventContent));
82
83 EXPECT_EQ(eventContent, expected);
84 EXPECT_TRUE(out.str().empty());
85 }
86 // Send second event
87 {
Ed Tanous6d799e12024-09-11 14:33:37 -070088 conn->sendSseEvent("TestEventId2", "TestEvent\nContent2");
Patrick Williamsbd79bce2024-08-16 15:22:20 -040089 constexpr std::string_view expected =
90 "id: TestEventId2\n"
91 "data: TestEvent\n"
92 "data: Content2\n"
93 "\n";
Ed Tanous8f79c5b2024-01-30 15:56:37 -080094
95 while (out.str().size() < expected.size())
96 {
97 io.run_for(std::chrono::milliseconds(1));
98 }
99
100 std::string eventContent;
101 eventContent.resize(expected.size());
102 boost::asio::read(out, boost::asio::buffer(eventContent));
103 EXPECT_EQ(eventContent, expected);
104 EXPECT_TRUE(out.str().empty());
105 }
106 // close the remote
107 {
108 out.close();
109 while (!closeCalled)
110 {
111 io.run_for(std::chrono::milliseconds(1));
112 }
113 }
114}
115} // namespace
116
117} // namespace sse_socket
118} // namespace crow