GCC Code Coverage Report


Directory: src/
File: src/message/msg-message-service.c
Date: 2024-07-13 00:54:47
Exec Total Coverage
Lines: 138 152 90.8%
Functions: 11 11 100.0%
Branches: 37 59 62.7%

Line Branch Exec Source
1 /* Copyright 2023-2024 Jan-Michael Brummer
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <libsoup/soup.h>
18 #include <json-glib/json-glib.h>
19
20 #include <stdio.h>
21
22 #include "msg-authorizer.h"
23 #include "msg-error.h"
24 #include "msg-private.h"
25 #include "msg-service.h"
26 #include "msg-message.h"
27 #include "msg-mail-folder.h"
28 #include "msg-message-service.h"
29
30 struct _MsgMessageService {
31 MsgService parent_instance;
32 };
33
34
6/7
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 11 times.
34 G_DEFINE_TYPE (MsgMessageService, msg_message_service, MSG_TYPE_SERVICE);
35
36 static void
37 1 msg_message_service_init (__attribute__ ((unused)) MsgMessageService *self)
38 {
39 1 }
40
41 static void
42 2 msg_message_service_class_init (__attribute__ ((unused)) MsgMessageServiceClass *class)
43 {
44 2 }
45
46 MsgMessageService *
47 1 msg_message_service_new (MsgAuthorizer *authorizer)
48 {
49 1 return g_object_new (MSG_TYPE_MESSAGE_SERVICE, "authorizer", authorizer, NULL);
50 }
51
52 /**
53 * msg_message_service_get_messages
54 * @self: a #MsgMessageService
55 * @cancellable: a #GCancellable
56 * @error: a #GError
57 *
58 * Get all messages for given service
59 *
60 * Returns: (element-type MsgMessage) (transfer full): all messages the user can access
61 */
62 GList *
63 1 msg_message_service_get_messages (MsgMessageService *self,
64 GCancellable *cancellable,
65 GError **error)
66 {
67 1 JsonObject *root_object = NULL;
68 1 g_autofree char *url = NULL;
69 1 g_autolist (MsgMessage) list = NULL;
70 1 JsonArray *array = NULL;
71 1 guint array_length = 0, index = 0;
72 1 g_autoptr (GBytes) response = NULL;
73 1 g_autoptr (JsonParser) parser = NULL;
74
75
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error))
76 return NULL;
77
78 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/messages", NULL);
79
80 do {
81
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 g_autoptr (SoupMessage) message = NULL;
82
83 1 message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE);
84 1 parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parser)
86 return NULL;
87
88 1 array = json_object_get_array_member (root_object, "value");
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_assert (array != NULL);
90
91 1 array_length = json_array_get_length (array);
92
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (index = 0; index < array_length; index++) {
93 1 g_autoptr (GError) local_error = NULL;
94 1 MsgMessage *msg = NULL;
95 1 JsonObject *message_object = NULL;
96
97 1 message_object = json_array_get_object_element (array, index);
98
99 1 msg = msg_message_new_from_json (message_object, &local_error);
100
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (msg) {
101 1 list = g_list_append (list, msg);
102 } else {
103 g_warning ("Could not parse message object: %s", local_error->message);
104 g_clear_error (&local_error);
105 }
106 }
107
108
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_clear_pointer (&url, g_free);
109 1 url = msg_service_get_next_link (root_object);
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } while (url != NULL);
111
112 1 return g_steal_pointer (&list);
113 }
114
115 /**
116 * msg_message_service_get_mail_folders
117 * @self: a #MsgMessageService
118 * @cancellable: a #GCancellable
119 * @error: a #GError
120 *
121 * Get all folders for given service
122 *
123 * Returns: (element-type MsgMailFolder) (transfer full): all mail folders the user can access
124 */
125 GList *
126 1 msg_message_service_get_mail_folders (MsgMessageService *self,
127 GCancellable *cancellable,
128 GError **error)
129 {
130 1 JsonObject *root_object = NULL;
131 1 g_autofree char *url = NULL;
132 1 g_autolist (MsgMailFolder) list = NULL;
133 1 JsonArray *array = NULL;
134 1 guint array_length = 0, index = 0;
135 1 g_autoptr (GBytes) response = NULL;
136 1 g_autoptr (JsonParser) parser = NULL;
137
138
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error))
139 return NULL;
140
141 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders", NULL);
142
143 do {
144
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 g_autoptr (SoupMessage) message = NULL;
145
146 1 message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE);
147 1 parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parser)
149 return NULL;
150
151 1 array = json_object_get_array_member (root_object, "value");
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_assert (array != NULL);
153
154 1 array_length = json_array_get_length (array);
155
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 for (index = 0; index < array_length; index++) {
156 8 g_autoptr (GError) local_error = NULL;
157 8 MsgMailFolder *folder = NULL;
158 8 JsonObject *object = NULL;
159
160 8 object = json_array_get_object_element (array, index);
161
162 8 folder = msg_mail_folder_new_from_json (object, &local_error);
163
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (folder) {
164 8 list = g_list_append (list, folder);
165 } else {
166 g_warning ("Could not parse mail folder object: %s", local_error->message);
167 g_clear_error (&local_error);
168 }
169 }
170
171
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_clear_pointer (&url, g_free);
172 1 url = msg_service_get_next_link (root_object);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } while (url != NULL);
174
175 1 return g_steal_pointer (&list);
176 }
177
178 /**
179 * msg_message_service_get_mail_folder
180 * @self: a #MsgMessageService
181 * @type: a #MsgMessageMailFolderType
182 * @cancellable: a #GCancellable
183 * @error: a #GError
184 *
185 * Get a specific mail folder for given service
186 *
187 * Returns: (transfer full): a #MsgMailFolder
188 */
189 MsgMailFolder *
190 7 msg_message_service_get_mail_folder (MsgMessageService *self,
191 MsgMessageMailFolderType type,
192 GCancellable *cancellable,
193 GError **error)
194 {
195 7 g_autoptr (SoupMessage) message = NULL;
196 7 g_autofree char *url = NULL;
197 7 g_autoptr (GBytes) response = NULL;
198 7 JsonObject *root_object = NULL;
199 7 g_autoptr (JsonParser) parser = NULL;
200
201
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error))
202 return NULL;
203
204
7/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
7 switch (type) {
205 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_INBOX:
206 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/inbox", NULL);
207 1 break;
208 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_DRAFTS:
209 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/drafts", NULL);
210 1 break;
211 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_SENT_ITEMS:
212 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/sentitems", NULL);
213 1 break;
214 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_JUNK_EMAIL:
215 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/junkemail", NULL);
216 1 break;
217 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_DELETED_ITEMS:
218 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/deleteditems", NULL);
219 1 break;
220 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_OUTBOX:
221 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/outbox", NULL);
222 1 break;
223 1 case MSG_MESSAGE_MAIL_FOLDER_TYPE_ARCHIVE:
224 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/mailFolders/archive", NULL);
225 1 break;
226 }
227
228 7 message = msg_service_build_message (MSG_SERVICE (self), "GET", url, NULL, FALSE);
229 7 parser = msg_service_send_and_parse_response (MSG_SERVICE (self), message, &root_object, cancellable, error);
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!parser)
231 return NULL;
232
233 7 return msg_mail_folder_new_from_json (root_object, error);
234 }
235
236 /**
237 * msg_message_service_delete:
238 * @self: a #MsgMessageService
239 * @message: a #MsgMessage
240 * @cancellable: a #GCancellable
241 * @error: a #GError
242 *
243 * Delets #message.
244 *
245 * Returns: %TRUE for succes, else &FALSE
246 */
247 gboolean
248 1 msg_message_service_delete (MsgMessageService *self,
249 MsgMessage *message,
250 GCancellable *cancellable,
251 GError **error)
252 {
253 1 g_autoptr (SoupMessage) soup_message = NULL;
254 1 g_autofree char *url = NULL;
255 1 g_autoptr (GBytes) response = NULL;
256 1 g_autoptr (JsonParser) parser = NULL;
257
258
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error))
259 return FALSE;
260
261 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/messages/", msg_message_get_id (message), NULL);
262 1 soup_message = msg_service_build_message (MSG_SERVICE (self), "DELETE", url, NULL, FALSE);
263 1 response = msg_service_send_and_read (MSG_SERVICE (self), soup_message, cancellable, error);
264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!response)
265 return FALSE;
266
267 1 return TRUE;
268 }
269
270 /**
271 * msg_message_service_create_draft:
272 * @self: a #MsgContextService
273 * @message: a #MsgMessage
274 * @cancellable: a #GCancellable
275 * @error: a #GError
276 *
277 * Create new draft message #message and return new message object.
278 *
279 * Returns: (transfer full): a new #MsgMessage
280 */
281 MsgMessage *
282 1 msg_message_service_create_draft (MsgMessageService *self,
283 MsgMessage *message,
284 GCancellable *cancellable,
285 GError **error)
286 {
287 1 g_autoptr (SoupMessage) soup_message = NULL;
288 1 JsonObject *root_object = NULL;
289 1 g_autofree char *url = NULL;
290 1 g_autoptr (JsonParser) parser = NULL;
291 1 g_autoptr (JsonBuilder) builder = NULL;
292 1 g_autoptr (JsonNode) node = NULL;
293 1 g_autofree char *json = NULL;
294 1 GBytes *body = NULL;
295
296
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!msg_service_refresh_authorization (MSG_SERVICE (self), cancellable, error))
297 return NULL;
298
299 1 url = g_strconcat (MSG_API_ENDPOINT, "/me/messages", NULL);
300 1 soup_message = msg_service_build_message (MSG_SERVICE (self), "POST", url, NULL, FALSE);
301
302 1 builder = json_builder_new ();
303 1 json_builder_begin_object (builder);
304 1 json_builder_set_member_name (builder, "subject");
305 1 json_builder_add_string_value (builder, msg_message_get_subject (message));
306
307 1 json_builder_set_member_name (builder, "body");
308 1 json_builder_begin_object (builder);
309 1 json_builder_set_member_name (builder, "content");
310 1 json_builder_add_string_value (builder, msg_message_get_body_preview (message));
311 1 json_builder_end_object (builder);
312 1 json_builder_end_object (builder);
313 1 node = json_builder_get_root (builder);
314 1 json = json_to_string (node, TRUE);
315
316 1 body = g_bytes_new (json, strlen (json));
317 1 soup_message_set_request_body_from_bytes (soup_message, "application/json", body);
318
319 1 parser = msg_service_send_and_parse_response (MSG_SERVICE (self), soup_message, &root_object, cancellable, error);
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parser)
321 return NULL;
322
323 1 return msg_message_new_from_json (root_object, error);
324 }
325