Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: components/security_state/content/web_contents_security_state_model_unittest.cc

Issue 2448943002: Refactor SecurityStateModel/Clients for simplicity and reusability. (Closed)
Patch Set: Remove *SecurityModelClient. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ssl/chrome_security_state_model_client.h" 5 #include "components/security_state/content/web_contents_security_state_model.h"
6 6
7 #include "components/security_state/security_state_model.h" 7 #include "components/security_state/core/security_state_model.h"
8 #include "content/public/browser/security_style_explanation.h" 8 #include "content/public/browser/security_style_explanation.h"
9 #include "content/public/browser/security_style_explanations.h" 9 #include "content/public/browser/security_style_explanations.h"
10 #include "net/cert/cert_status_flags.h" 10 #include "net/cert/cert_status_flags.h"
11 #include "net/ssl/ssl_cipher_suite_names.h" 11 #include "net/ssl/ssl_cipher_suite_names.h"
12 #include "net/ssl/ssl_connection_status_flags.h" 12 #include "net/ssl/ssl_connection_status_flags.h"
13 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
14 14
15 namespace { 15 namespace {
16 16
17 using security_state::WebContentsSecurityStateModel;
18
17 // Tests that SecurityInfo flags for subresources with certificate 19 // Tests that SecurityInfo flags for subresources with certificate
18 // errors are reflected in the SecurityStyleExplanations produced by 20 // errors are reflected in the SecurityStyleExplanations produced by
19 // ChromeSecurityStateModelClient. 21 // WebContentsSecurityStateModel.
20 TEST(ChromeSecurityStateModelClientTest, 22 TEST(WebContentsSecurityStateModelTest,
21 GetSecurityStyleForContentWithCertErrors) { 23 GetSecurityStyleForContentWithCertErrors) {
22 content::SecurityStyleExplanations explanations; 24 content::SecurityStyleExplanations explanations;
23 security_state::SecurityStateModel::SecurityInfo security_info; 25 security_state::SecurityStateModel::SecurityInfo security_info;
24 security_info.cert_status = 0; 26 security_info.cert_status = 0;
25 security_info.scheme_is_cryptographic = true; 27 security_info.scheme_is_cryptographic = true;
26 28
27 security_info.content_with_cert_errors_status = 29 security_info.content_with_cert_errors_status =
28 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; 30 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
29 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 31 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
30 &explanations);
31 EXPECT_TRUE(explanations.ran_content_with_cert_errors); 32 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
32 EXPECT_TRUE(explanations.displayed_content_with_cert_errors); 33 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
33 34
34 security_info.content_with_cert_errors_status = 35 security_info.content_with_cert_errors_status =
35 security_state::SecurityStateModel::CONTENT_STATUS_RAN; 36 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
36 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 37 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
37 &explanations);
38 EXPECT_TRUE(explanations.ran_content_with_cert_errors); 38 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
39 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 39 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
40 40
41 security_info.content_with_cert_errors_status = 41 security_info.content_with_cert_errors_status =
42 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED; 42 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
43 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 43 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
44 &explanations);
45 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 44 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
46 EXPECT_TRUE(explanations.displayed_content_with_cert_errors); 45 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
47 46
48 security_info.content_with_cert_errors_status = 47 security_info.content_with_cert_errors_status =
49 security_state::SecurityStateModel::CONTENT_STATUS_NONE; 48 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
50 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 49 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
51 &explanations);
52 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 50 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
53 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 51 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
54 } 52 }
55 53
56 // Tests that SecurityStyleExplanations for subresources with cert 54 // Tests that SecurityStyleExplanations for subresources with cert
57 // errors are *not* set when the main resource has major certificate 55 // errors are *not* set when the main resource has major certificate
58 // errors. If the main resource has certificate errors, it would be 56 // errors. If the main resource has certificate errors, it would be
59 // duplicative/confusing to also report subresources with cert errors. 57 // duplicative/confusing to also report subresources with cert errors.
60 TEST(ChromeSecurityStateModelClientTest, 58 TEST(WebContentsSecurityStateModelTest,
61 SubresourcesAndMainResourceWithMajorCertErrors) { 59 SubresourcesAndMainResourceWithMajorCertErrors) {
62 content::SecurityStyleExplanations explanations; 60 content::SecurityStyleExplanations explanations;
63 security_state::SecurityStateModel::SecurityInfo security_info; 61 security_state::SecurityStateModel::SecurityInfo security_info;
64 security_info.cert_status = net::CERT_STATUS_DATE_INVALID; 62 security_info.cert_status = net::CERT_STATUS_DATE_INVALID;
65 security_info.scheme_is_cryptographic = true; 63 security_info.scheme_is_cryptographic = true;
66 64
67 security_info.content_with_cert_errors_status = 65 security_info.content_with_cert_errors_status =
68 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; 66 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
69 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 67 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
70 &explanations);
71 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 68 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
72 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 69 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
73 70
74 security_info.content_with_cert_errors_status = 71 security_info.content_with_cert_errors_status =
75 security_state::SecurityStateModel::CONTENT_STATUS_RAN; 72 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
76 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 73 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
77 &explanations);
78 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 74 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
79 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 75 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
80 76
81 security_info.content_with_cert_errors_status = 77 security_info.content_with_cert_errors_status =
82 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED; 78 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
83 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 79 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
84 &explanations);
85 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 80 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
86 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 81 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
87 82
88 security_info.content_with_cert_errors_status = 83 security_info.content_with_cert_errors_status =
89 security_state::SecurityStateModel::CONTENT_STATUS_NONE; 84 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
90 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 85 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
91 &explanations);
92 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 86 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
93 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 87 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
94 } 88 }
95 89
96 // Tests that SecurityStyleExplanations for subresources with cert 90 // Tests that SecurityStyleExplanations for subresources with cert
97 // errors are set when the main resource has only minor certificate 91 // errors are set when the main resource has only minor certificate
98 // errors. Minor errors on the main resource should not hide major 92 // errors. Minor errors on the main resource should not hide major
99 // errors on subresources. 93 // errors on subresources.
100 TEST(ChromeSecurityStateModelClientTest, 94 TEST(WebContentsSecurityStateModelTest,
101 SubresourcesAndMainResourceWithMinorCertErrors) { 95 SubresourcesAndMainResourceWithMinorCertErrors) {
102 content::SecurityStyleExplanations explanations; 96 content::SecurityStyleExplanations explanations;
103 security_state::SecurityStateModel::SecurityInfo security_info; 97 security_state::SecurityStateModel::SecurityInfo security_info;
104 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; 98 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
105 security_info.scheme_is_cryptographic = true; 99 security_info.scheme_is_cryptographic = true;
106 100
107 security_info.content_with_cert_errors_status = 101 security_info.content_with_cert_errors_status =
108 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; 102 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
109 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 103 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
110 &explanations);
111 EXPECT_TRUE(explanations.ran_content_with_cert_errors); 104 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
112 EXPECT_TRUE(explanations.displayed_content_with_cert_errors); 105 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
113 106
114 security_info.content_with_cert_errors_status = 107 security_info.content_with_cert_errors_status =
115 security_state::SecurityStateModel::CONTENT_STATUS_RAN; 108 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
116 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 109 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
117 &explanations);
118 EXPECT_TRUE(explanations.ran_content_with_cert_errors); 110 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
119 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 111 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
120 112
121 security_info.content_with_cert_errors_status = 113 security_info.content_with_cert_errors_status =
122 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED; 114 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
123 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 115 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
124 &explanations);
125 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 116 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
126 EXPECT_TRUE(explanations.displayed_content_with_cert_errors); 117 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
127 118
128 security_info.content_with_cert_errors_status = 119 security_info.content_with_cert_errors_status =
129 security_state::SecurityStateModel::CONTENT_STATUS_NONE; 120 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
130 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 121 WebContentsSecurityStateModel::GetSecurityStyle(security_info, &explanations);
131 &explanations);
132 EXPECT_FALSE(explanations.ran_content_with_cert_errors); 122 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
133 EXPECT_FALSE(explanations.displayed_content_with_cert_errors); 123 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
134 } 124 }
135 125
136 bool FindSecurityStyleExplanation( 126 bool FindSecurityStyleExplanation(
137 const std::vector<content::SecurityStyleExplanation>& explanations, 127 const std::vector<content::SecurityStyleExplanation>& explanations,
138 const char* summary, 128 const char* summary,
139 content::SecurityStyleExplanation* explanation) { 129 content::SecurityStyleExplanation* explanation) {
140 for (const auto& entry : explanations) { 130 for (const auto& entry : explanations) {
141 if (entry.summary == summary) { 131 if (entry.summary == summary) {
142 *explanation = entry; 132 *explanation = entry;
143 return true; 133 return true;
144 } 134 }
145 } 135 }
146 136
147 return false; 137 return false;
148 } 138 }
149 139
150 // Test that connection explanations are formated as expected. Note the strings 140 // Test that connection explanations are formated as expected. Note the strings
151 // are not translated and so will be the same in any locale. 141 // are not translated and so will be the same in any locale.
152 TEST(ChromeSecurityStateModelClientTest, ConnectionExplanation) { 142 TEST(WebContentsSecurityStateModelTest, ConnectionExplanation) {
153 // Test a modern configuration with a key exchange group. 143 // Test a modern configuration with a key exchange group.
154 security_state::SecurityStateModel::SecurityInfo security_info; 144 security_state::SecurityStateModel::SecurityInfo security_info;
155 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; 145 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
156 security_info.scheme_is_cryptographic = true; 146 security_info.scheme_is_cryptographic = true;
157 net::SSLConnectionStatusSetCipherSuite( 147 net::SSLConnectionStatusSetCipherSuite(
158 0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */, 148 0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
159 &security_info.connection_status); 149 &security_info.connection_status);
160 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2, 150 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
161 &security_info.connection_status); 151 &security_info.connection_status);
162 security_info.key_exchange_group = 29; // X25519 152 security_info.key_exchange_group = 29; // X25519
163 153
164 { 154 {
165 content::SecurityStyleExplanations explanations; 155 content::SecurityStyleExplanations explanations;
166 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 156 WebContentsSecurityStateModel::GetSecurityStyle(security_info,
167 &explanations); 157 &explanations);
168 content::SecurityStyleExplanation explanation; 158 content::SecurityStyleExplanation explanation;
169 ASSERT_TRUE(FindSecurityStyleExplanation( 159 ASSERT_TRUE(FindSecurityStyleExplanation(
170 explanations.secure_explanations, "Secure Connection", &explanation)); 160 explanations.secure_explanations, "Secure Connection", &explanation));
171 EXPECT_EQ( 161 EXPECT_EQ(
172 "The connection to this site is encrypted and authenticated using a " 162 "The connection to this site is encrypted and authenticated using a "
173 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with " 163 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with "
174 "X25519), and a strong cipher (CHACHA20_POLY1305).", 164 "X25519), and a strong cipher (CHACHA20_POLY1305).",
175 explanation.description); 165 explanation.description);
176 } 166 }
177 167
178 // Some older cache entries may be missing the key exchange group, despite 168 // Some older cache entries may be missing the key exchange group, despite
179 // having a cipher which should supply one. 169 // having a cipher which should supply one.
180 security_info.key_exchange_group = 0; 170 security_info.key_exchange_group = 0;
181 { 171 {
182 content::SecurityStyleExplanations explanations; 172 content::SecurityStyleExplanations explanations;
183 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 173 WebContentsSecurityStateModel::GetSecurityStyle(security_info,
184 &explanations); 174 &explanations);
185 content::SecurityStyleExplanation explanation; 175 content::SecurityStyleExplanation explanation;
186 ASSERT_TRUE(FindSecurityStyleExplanation( 176 ASSERT_TRUE(FindSecurityStyleExplanation(
187 explanations.secure_explanations, "Secure Connection", &explanation)); 177 explanations.secure_explanations, "Secure Connection", &explanation));
188 EXPECT_EQ( 178 EXPECT_EQ(
189 "The connection to this site is encrypted and authenticated using a " 179 "The connection to this site is encrypted and authenticated using a "
190 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA), and a " 180 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA), and a "
191 "strong cipher (CHACHA20_POLY1305).", 181 "strong cipher (CHACHA20_POLY1305).",
192 explanation.description); 182 explanation.description);
193 } 183 }
194 184
195 // TLS 1.3 ciphers use the key exchange group exclusively. 185 // TLS 1.3 ciphers use the key exchange group exclusively.
196 net::SSLConnectionStatusSetCipherSuite(0x1301 /* TLS_AES_128_GCM_SHA256 */, 186 net::SSLConnectionStatusSetCipherSuite(0x1301 /* TLS_AES_128_GCM_SHA256 */,
197 &security_info.connection_status); 187 &security_info.connection_status);
198 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_3, 188 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_3,
199 &security_info.connection_status); 189 &security_info.connection_status);
200 security_info.key_exchange_group = 29; // X25519 190 security_info.key_exchange_group = 29; // X25519
201 { 191 {
202 content::SecurityStyleExplanations explanations; 192 content::SecurityStyleExplanations explanations;
203 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 193 WebContentsSecurityStateModel::GetSecurityStyle(security_info,
204 &explanations); 194 &explanations);
205 content::SecurityStyleExplanation explanation; 195 content::SecurityStyleExplanation explanation;
206 ASSERT_TRUE(FindSecurityStyleExplanation( 196 ASSERT_TRUE(FindSecurityStyleExplanation(
207 explanations.secure_explanations, "Secure Connection", &explanation)); 197 explanations.secure_explanations, "Secure Connection", &explanation));
208 EXPECT_EQ( 198 EXPECT_EQ(
209 "The connection to this site is encrypted and authenticated using a " 199 "The connection to this site is encrypted and authenticated using a "
210 "strong protocol (TLS 1.3), a strong key exchange (X25519), and a " 200 "strong protocol (TLS 1.3), a strong key exchange (X25519), and a "
211 "strong cipher (AES_128_GCM).", 201 "strong cipher (AES_128_GCM).",
212 explanation.description); 202 explanation.description);
213 } 203 }
214 } 204 }
215 205
216 // Tests that a security level of HTTP_SHOW_WARNING produces a 206 // Tests that a security level of HTTP_SHOW_WARNING produces a
217 // content::SecurityStyle of UNAUTHENTICATED, with an explanation. 207 // content::SecurityStyle of UNAUTHENTICATED, with an explanation.
218 TEST(ChromeSecurityStateModelClientTest, HTTPWarning) { 208 TEST(WebContentsSecurityStateModelTest, HTTPWarning) {
219 security_state::SecurityStateModel::SecurityInfo security_info; 209 security_state::SecurityStateModel::SecurityInfo security_info;
220 content::SecurityStyleExplanations explanations; 210 content::SecurityStyleExplanations explanations;
221 security_info.security_level = 211 security_info.security_level =
222 security_state::SecurityStateModel::HTTP_SHOW_WARNING; 212 security_state::SecurityStateModel::HTTP_SHOW_WARNING;
223 blink::WebSecurityStyle security_style = 213 blink::WebSecurityStyle security_style =
224 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 214 WebContentsSecurityStateModel::GetSecurityStyle(security_info,
225 &explanations); 215 &explanations);
226 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style); 216 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style);
227 EXPECT_EQ(1u, explanations.unauthenticated_explanations.size()); 217 EXPECT_EQ(1u, explanations.unauthenticated_explanations.size());
228 } 218 }
229 219
230 // Tests that a security level of NONE when there is a password or 220 // Tests that a security level of NONE when there is a password or
231 // credit card field on HTTP produces a content::SecurityStyle of 221 // credit card field on HTTP produces a content::SecurityStyle of
232 // UNAUTHENTICATED, with an info explanation. 222 // UNAUTHENTICATED, with an info explanation.
233 TEST(ChromeSecurityStateModelClientTest, HTTPWarningInFuture) { 223 TEST(WebContentsSecurityStateModelTest, HTTPWarningInFuture) {
234 security_state::SecurityStateModel::SecurityInfo security_info; 224 security_state::SecurityStateModel::SecurityInfo security_info;
235 content::SecurityStyleExplanations explanations; 225 content::SecurityStyleExplanations explanations;
236 security_info.security_level = security_state::SecurityStateModel::NONE; 226 security_info.security_level = security_state::SecurityStateModel::NONE;
237 security_info.displayed_private_user_data_input_on_http = true; 227 security_info.displayed_private_user_data_input_on_http = true;
238 blink::WebSecurityStyle security_style = 228 blink::WebSecurityStyle security_style =
239 ChromeSecurityStateModelClient::GetSecurityStyle(security_info, 229 WebContentsSecurityStateModel::GetSecurityStyle(security_info,
240 &explanations); 230 &explanations);
241 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style); 231 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style);
242 EXPECT_EQ(1u, explanations.info_explanations.size()); 232 EXPECT_EQ(1u, explanations.info_explanations.size());
243 } 233 }
244 234
245 } // namespace 235 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698