1 // Copyright 2016 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "ewk/unittest/utc_blink_ewk_base.h"
12 class utc_blink_ewk_intercept_request_response_write_chunk
13 : public utc_blink_ewk_base {
15 utc_blink_ewk_intercept_request_response_write_chunk()
16 : status_set_result_(false),
17 content_type_header_result_(false),
18 content_length_header_result_(false),
20 null_intercept_request_(false),
23 chunk_write_timer_(nullptr),
24 intercept_request_(nullptr),
25 callback_called_(false) {
26 body_.append(kBodyPre);
28 body_.append(kBodyPost);
29 body_length_ = body_.length();
30 data_to_write_ = body_length_;
34 static const char* kInterceptURL;
35 static const char* kBodyPre;
36 static const char* kTitle;
37 static const char* kBodyPost;
38 // Chunk should be smaller than payload for this test.
39 static const size_t kDefaultChunkLength;
41 void LoadFinished(Evas_Object* webview) override { EventLoopStop(Success); }
43 void PostSetUp() override {
44 ewk_context_intercept_request_callback_set(
45 ewk_view_context_get(GetEwkWebView()), intercept_request_callback,
49 void PreTearDown() override {
50 if (chunk_write_timer_)
51 ecore_timer_del(chunk_write_timer_);
54 void PrepareAndStartChunkWrite(MainLoopResult expected_result) {
55 ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), kInterceptURL));
56 ASSERT_EQ(Timeout, EventLoopStart(3.0));
57 ASSERT_TRUE(callback_called_.load());
58 EXPECT_TRUE(status_set_result_);
59 EXPECT_TRUE(content_type_header_result_);
60 EXPECT_TRUE(content_length_header_result_);
61 SetTestJob(utc_blink_ewk_intercept_request_response_write_chunk::
63 ASSERT_EQ(expected_result, EventLoopStart());
66 static void intercept_request_callback(
68 Ewk_Intercept_Request* intercept_request,
71 static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
74 const char* url = ewk_intercept_request_url_get(intercept_request);
75 if (strcmp(url, kInterceptURL) == 0) {
76 owner->status_set_result_ = ewk_intercept_request_response_status_set(
77 intercept_request, 200, nullptr);
78 owner->content_type_header_result_ =
79 ewk_intercept_request_response_header_add(
80 intercept_request, "Content-Type", "text/html; charset=UTF-8");
81 owner->content_length_header_result_ =
82 ewk_intercept_request_response_header_add(
83 intercept_request, "Content-Length",
84 std::to_string(owner->body_length_).c_str());
85 if (owner->null_intercept_request_)
86 owner->intercept_request_ = nullptr;
88 owner->intercept_request_ = intercept_request;
90 // Ignore any other request.
91 ewk_intercept_request_ignore(intercept_request);
93 owner->callback_called_.store(true);
96 static Eina_Bool chunk_write_callback(void* data) {
98 static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
100 size_t to_write = std::min(kDefaultChunkLength, owner->data_to_write_);
102 const char* chunk = owner->null_chunk_
104 : owner->body_.c_str() + owner->data_written_;
105 Eina_Bool write_success = ewk_intercept_request_response_write_chunk(
106 owner->intercept_request_, chunk, to_write);
107 if (!write_success) {
108 owner->EventLoopStop(Failure);
109 owner->chunk_write_timer_ = nullptr;
110 return ECORE_CALLBACK_CANCEL;
112 owner->data_to_write_ -= to_write;
113 owner->data_written_ += to_write;
114 return ECORE_CALLBACK_RENEW;
116 owner->last_write_ = ewk_intercept_request_response_write_chunk(
117 owner->intercept_request_, nullptr, 0);
118 owner->chunk_write_timer_ = nullptr;
119 return ECORE_CALLBACK_CANCEL;
123 static void job_do_chunk_write(utc_blink_ewk_base* data) {
125 static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
127 // Writing happens outside of callback.
128 // Use timer with non-zero timeout to show async nature of this API.
129 owner->chunk_write_timer_ =
130 ecore_timer_add(0.01, (Ecore_Task_Cb)chunk_write_callback, owner);
133 bool status_set_result_;
134 bool content_type_header_result_;
135 bool content_length_header_result_;
138 bool null_intercept_request_;
140 size_t data_to_write_;
141 size_t data_written_;
144 Ecore_Timer* chunk_write_timer_;
145 Ewk_Intercept_Request* intercept_request_;
146 std::atomic<bool> callback_called_;
150 utc_blink_ewk_intercept_request_response_write_chunk::kInterceptURL =
151 "http://request.intercept.ewk.api.test/";
153 const char* utc_blink_ewk_intercept_request_response_write_chunk::kBodyPre =
154 "<html><head><title>";
155 const char* utc_blink_ewk_intercept_request_response_write_chunk::kBodyPost =
157 "<body>Hello, Request Intercept!</body></html>";
158 const char* utc_blink_ewk_intercept_request_response_write_chunk::kTitle =
159 "CHUNKED WRITE SUCCESS";
161 utc_blink_ewk_intercept_request_response_write_chunk::kDefaultChunkLength =
165 * @brief Tests if writing response in chunks for intercepted request results
166 * in expected web page.
168 TEST_F(utc_blink_ewk_intercept_request_response_write_chunk,
169 POS_TEST_WRITE_RESPONSE_IN_CHUNKS) {
170 PrepareAndStartChunkWrite(Success);
171 EXPECT_FALSE(last_write_);
172 EXPECT_STREQ(kTitle, ewk_view_title_get(GetEwkWebView()));
176 * @brief Tests if EINA_FALSE is returned for null intercept request.
178 TEST_F(utc_blink_ewk_intercept_request_response_write_chunk,
179 NEG_TEST_NULL_INTERCEPT_REQUEST) {
180 null_intercept_request_ = true;
181 PrepareAndStartChunkWrite(Failure);
185 * @brief Tests if EINA_FALSE is returned for null body chunk.
187 TEST_F(utc_blink_ewk_intercept_request_response_write_chunk,
188 NEG_TEST_NULL_BODY_CHUNK) {
190 PrepareAndStartChunkWrite(Failure);