[M120 Migration][MM] Support W3C EME
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / unittest / utc_blink_ewk_intercept_request_response_write_chunk_func.cpp
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.
4
5 #include <algorithm>
6 #include <atomic>
7 #include <cstring>
8 #include <string>
9
10 #include "ewk/unittest/utc_blink_ewk_base.h"
11
12 class utc_blink_ewk_intercept_request_response_write_chunk
13     : public utc_blink_ewk_base {
14  public:
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),
19         last_write_(true),
20         null_intercept_request_(false),
21         null_chunk_(false),
22         data_written_(0),
23         chunk_write_timer_(nullptr),
24         intercept_request_(nullptr),
25         callback_called_(false) {
26     body_.append(kBodyPre);
27     body_.append(kTitle);
28     body_.append(kBodyPost);
29     body_length_ = body_.length();
30     data_to_write_ = body_length_;
31   }
32
33  protected:
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;
40
41   void LoadFinished(Evas_Object* webview) override { EventLoopStop(Success); }
42
43   void PostSetUp() override {
44     ewk_context_intercept_request_callback_set(
45         ewk_view_context_get(GetEwkWebView()), intercept_request_callback,
46         this);
47   }
48
49   void PreTearDown() override {
50     if (chunk_write_timer_)
51       ecore_timer_del(chunk_write_timer_);
52   }
53
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::
62                    job_do_chunk_write);
63     ASSERT_EQ(expected_result, EventLoopStart());
64   }
65
66   static void intercept_request_callback(
67       Ewk_Context* /*ctx*/,
68       Ewk_Intercept_Request* intercept_request,
69       void* user_data) {
70     auto* owner =
71         static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
72             user_data);
73
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;
87       else
88         owner->intercept_request_ = intercept_request;
89     } else {
90       // Ignore any other request.
91       ewk_intercept_request_ignore(intercept_request);
92     }
93     owner->callback_called_.store(true);
94   }
95
96   static Eina_Bool chunk_write_callback(void* data) {
97     auto* owner =
98         static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
99             data);
100     size_t to_write = std::min(kDefaultChunkLength, owner->data_to_write_);
101     if (to_write) {
102       const char* chunk = owner->null_chunk_
103                               ? nullptr
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;
111       }
112       owner->data_to_write_ -= to_write;
113       owner->data_written_ += to_write;
114       return ECORE_CALLBACK_RENEW;
115     } else {
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;
120     }
121   }
122
123   static void job_do_chunk_write(utc_blink_ewk_base* data) {
124     auto owner =
125         static_cast<utc_blink_ewk_intercept_request_response_write_chunk*>(
126             data);
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);
131   }
132
133   bool status_set_result_;
134   bool content_type_header_result_;
135   bool content_length_header_result_;
136   bool last_write_;
137
138   bool null_intercept_request_;
139   bool null_chunk_;
140   size_t data_to_write_;
141   size_t data_written_;
142   std::string body_;
143   size_t body_length_;
144   Ecore_Timer* chunk_write_timer_;
145   Ewk_Intercept_Request* intercept_request_;
146   std::atomic<bool> callback_called_;
147 };
148
149 const char*
150     utc_blink_ewk_intercept_request_response_write_chunk::kInterceptURL =
151         "http://request.intercept.ewk.api.test/";
152
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 =
156     "</title></head>"
157     "<body>Hello, Request Intercept!</body></html>";
158 const char* utc_blink_ewk_intercept_request_response_write_chunk::kTitle =
159     "CHUNKED WRITE SUCCESS";
160 const size_t
161     utc_blink_ewk_intercept_request_response_write_chunk::kDefaultChunkLength =
162         5;
163
164 /**
165  * @brief Tests if writing response in chunks for intercepted request results
166  *        in expected web page.
167  */
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()));
173 }
174
175 /**
176  * @brief Tests if EINA_FALSE is returned for null intercept request.
177  */
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);
182 }
183
184 /**
185  * @brief Tests if EINA_FALSE is returned for null body chunk.
186  */
187 TEST_F(utc_blink_ewk_intercept_request_response_write_chunk,
188        NEG_TEST_NULL_BODY_CHUNK) {
189   null_chunk_ = true;
190   PrepareAndStartChunkWrite(Failure);
191 }