1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "google/cloud/storage/internal/notification_requests.h"
16 #include "google/cloud/storage/notification_event_type.h"
17 #include "google/cloud/storage/notification_payload_format.h"
18 #include <gmock/gmock.h>
19
20 namespace google {
21 namespace cloud {
22 namespace storage {
23 inline namespace STORAGE_CLIENT_NS {
24 namespace internal {
25 namespace {
26
27 using ::testing::HasSubstr;
28
29 /// @test Verify that we parse JSON objects into NotificationMetadata objects.
TEST(NotificationRequestTest,Parse)30 TEST(NotificationRequestTest, Parse) {
31 auto actual = NotificationMetadataParser::FromString(R"""({
32 "custom_attributes": {
33 "test-ca-1": "value1",
34 "test-ca-2": "value2"
35 },
36 "etag": "XYZ=",
37 "event_types": [
38 "OBJECT_FINALIZE",
39 "OBJECT_METADATA_UPDATE",
40 "OBJECT_DELETE",
41 "OBJECT_ARCHIVE"
42 ],
43 "id": "test-id-123",
44 "kind": "storage#notification",
45 "object_name_prefix": "test-prefix-",
46 "payload_format": "JSON_API_V1",
47 "selfLink": "https://storage.googleapis.com/storage/v1/b/test-bucket/notificationConfigs/test-id-123",
48 "topic": "test-topic"
49 })""")
50 .value();
51 EXPECT_EQ(2, actual.custom_attributes().size());
52 EXPECT_TRUE(actual.has_custom_attribute("test-ca-1"));
53 EXPECT_EQ("value1", actual.custom_attribute("test-ca-1"));
54 EXPECT_TRUE(actual.has_custom_attribute("test-ca-2"));
55 EXPECT_EQ("value2", actual.custom_attribute("test-ca-2"));
56
57 EXPECT_EQ("XYZ=", actual.etag());
58 EXPECT_EQ(4, actual.event_type_size());
59 EXPECT_EQ(4, actual.event_types().size());
60 EXPECT_EQ(event_type::ObjectFinalize(), actual.event_type(0));
61 EXPECT_EQ(event_type::ObjectMetadataUpdate(), actual.event_type(1));
62 EXPECT_EQ(event_type::ObjectDelete(), actual.event_type(2));
63 EXPECT_EQ(event_type::ObjectArchive(), actual.event_type(3));
64
65 EXPECT_EQ("test-id-123", actual.id());
66 EXPECT_EQ("storage#notification", actual.kind());
67 EXPECT_EQ(payload_format::JsonApiV1(), actual.payload_format());
68 EXPECT_EQ(
69 "https://storage.googleapis.com/storage/v1/b/test-bucket/"
70 "notificationConfigs/test-id-123",
71 actual.self_link());
72 EXPECT_EQ("test-topic", actual.topic());
73 }
74
75 /// @test Verify that we parse JSON objects into NotificationMetadata objects.
TEST(NotificationRequestTest,ParseFailure)76 TEST(NotificationRequestTest, ParseFailure) {
77 auto actual = internal::NotificationMetadataParser::FromString("{123");
78 EXPECT_FALSE(actual.ok());
79 }
80
TEST(NotificationRequestTest,List)81 TEST(NotificationRequestTest, List) {
82 ListNotificationsRequest request("my-bucket");
83 request.set_multiple_options(UserProject("project-for-billing"));
84 EXPECT_EQ("my-bucket", request.bucket_name());
85
86 std::ostringstream os;
87 os << request;
88 auto str = os.str();
89 EXPECT_THAT(str, HasSubstr("userProject=project-for-billing"));
90 EXPECT_THAT(str, HasSubstr("my-bucket"));
91 }
92
TEST(NotificationRequestTest,ListResponse)93 TEST(NotificationRequestTest, ListResponse) {
94 std::string text = R"""({
95 "items": [{
96 "id": "test-notification-id-1",
97 "topic": "test-topic-1"
98 }, {
99 "id": "test-notification-id-2",
100 "topic": "test-topic-2"
101 }]})""";
102
103 auto actual = ListNotificationsResponse::FromHttpResponse(text).value();
104 ASSERT_EQ(2UL, actual.items.size());
105 EXPECT_EQ("test-notification-id-1", actual.items.at(0).id());
106 EXPECT_EQ("test-topic-1", actual.items.at(0).topic());
107 EXPECT_EQ("test-notification-id-2", actual.items.at(1).id());
108 EXPECT_EQ("test-topic-2", actual.items.at(1).topic());
109
110 std::ostringstream os;
111 os << actual;
112 auto str = os.str();
113 EXPECT_THAT(str, HasSubstr("id=test-notification-id-1"));
114 EXPECT_THAT(str, HasSubstr("id=test-notification-id-2"));
115 EXPECT_THAT(str, HasSubstr("ListNotificationResponse={"));
116 EXPECT_THAT(str, HasSubstr("NotificationMetadata={"));
117 }
118
TEST(NotificationRequestTest,ListResponseParseFailure)119 TEST(NotificationRequestTest, ListResponseParseFailure) {
120 std::string text = R"""({123)""";
121
122 StatusOr<ListNotificationsResponse> actual =
123 ListNotificationsResponse::FromHttpResponse(text);
124 EXPECT_FALSE(actual.ok());
125 }
126
TEST(NotificationRequestTest,ListResponseParseFailureListElements)127 TEST(NotificationRequestTest, ListResponseParseFailureListElements) {
128 std::string text = R"""({
129 "items": [{
130 "id": "test-notification-id-1",
131 "topic": "test-topic-1"
132 }, "invalid-element"]})""";
133
134 StatusOr<ListNotificationsResponse> actual =
135 ListNotificationsResponse::FromHttpResponse(text);
136 EXPECT_FALSE(actual.ok());
137 }
138
TEST(CreateNotificationRequestTest,Create)139 TEST(CreateNotificationRequestTest, Create) {
140 NotificationMetadata notification =
141 NotificationMetadata()
142 .set_topic("test-topic-1")
143 .set_payload_format(payload_format::JsonApiV1())
144 .set_object_name_prefix("test-object-prefix-");
145 CreateNotificationRequest request("my-bucket", notification);
146 request.set_multiple_options(UserProject("project-for-billing"));
147 EXPECT_EQ("my-bucket", request.bucket_name());
148 EXPECT_EQ(notification.JsonPayloadForInsert(), request.json_payload());
149
150 std::ostringstream os;
151 os << request;
152 auto str = os.str();
153 EXPECT_THAT(str, HasSubstr("userProject=project-for-billing"));
154 EXPECT_THAT(str, HasSubstr("my-bucket"));
155 EXPECT_THAT(str, HasSubstr(notification.JsonPayloadForInsert()));
156 }
157
TEST(NotificationRequestTest,Get)158 TEST(NotificationRequestTest, Get) {
159 GetNotificationRequest request("my-bucket", "test-notification-id");
160 request.set_multiple_options(UserProject("my-project"));
161 EXPECT_EQ("my-bucket", request.bucket_name());
162 EXPECT_EQ("test-notification-id", request.notification_id());
163 std::ostringstream os;
164 os << request;
165 auto str = os.str();
166 EXPECT_THAT(str, HasSubstr("userProject=my-project"));
167 EXPECT_THAT(str, HasSubstr("my-bucket"));
168 EXPECT_THAT(str, HasSubstr("test-notification-id"));
169 }
170
TEST(NotificationRequestTest,Delete)171 TEST(NotificationRequestTest, Delete) {
172 DeleteNotificationRequest request("my-bucket", "test-notification-id");
173 request.set_multiple_options(UserProject("my-project"));
174 EXPECT_EQ("my-bucket", request.bucket_name());
175 EXPECT_EQ("test-notification-id", request.notification_id());
176 std::ostringstream os;
177 os << request;
178 auto str = os.str();
179 EXPECT_THAT(str, HasSubstr("userProject=my-project"));
180 EXPECT_THAT(str, HasSubstr("my-bucket"));
181 EXPECT_THAT(str, HasSubstr("test-notification-id"));
182 }
183
184 } // namespace
185 } // namespace internal
186 } // namespace STORAGE_CLIENT_NS
187 } // namespace storage
188 } // namespace cloud
189 } // namespace google
190