about summary refs log tree commit diff stats
Commit message (Collapse)AuthorAgeFilesLines
* :exec, :pipe: show exit status on completionDrew DeVault2019-07-082-2/+4
|
* aerc(1): correct error with :pipe documentationDrew DeVault2019-07-081-0/+2
|
* Add :exec and :pipe -b(ackground)Drew DeVault2019-07-083-25/+104
|
* Factor IMAP-specific structs out of UI modelsBen Burwell2019-07-0810-108/+211
| | | | | | | Before, we were using several IMAP-specific concepts to represent information being displayed in the UI. Factor these structures out of the IMAP package to make it easier for other backends to provide the required information.
* Use []uint32 instead of imap.SeqSetBen Burwell2019-07-086-41/+41
| | | | | | | | A sequence-set is an IMAP-specific implementation detail. Throughout the UI, aerc simply operates using lists of opaque identifiers. In order to loosen the coupling between the UI and IMAP in particular, replace most usages of imap.SeqSet with []uint32, leaving the translation to a SeqSet to the IMAP backend as needed.
* Factor UI models out of the worker message packageBen Burwell2019-07-0812-86/+146
| | | | | | | | Before, the information needed to display different parts of the UI was tightly coupled to the specific messages being sent back and forth to the backend worker. Separating out a models package allows us to be more specific about exactly what a backend is able to and required to provide for the UI.
* Add .build.ymlDrew DeVault2019-07-071-0/+24
|
* Make :pipe command more genericDrew DeVault2019-07-058-110/+125
|
* Remove unused caps stringDrew DeVault2019-07-041-2/+0
|
* Sort out dirstore once and for allDrew DeVault2019-07-043-16/+2
|
* dirlist: simplify nextPrev() considerablyReto Brunner2019-07-041-25/+11
| | | | | | | Assuming we always have a sorted dirlist (other code depends on that already), we don't need to loop over the dirStore. Any filtering done should be performed elsewhere
* dirlist: remove the additional filtering in Draw()Reto Brunner2019-07-041-7/+0
|
* dirlist: sync dirstore in filterDirsByFoldersConfigReto Brunner2019-07-041-9/+7
| | | | | Also sets the public List() method to return the unfiltered list of directories directly from the store.
* Add IMAP folder tab completionGregory Mullen2019-07-044-3/+32
| | | | | Credit for this fix goes to Reto; I guess if we're not gonna be mutt we should probabaly do things correctly.
* Use go-message implementation of GenerateMessageIDBen Burwell2019-07-042-36/+1
| | | | | Now that this is available in the upstream, we no longer need to maintain a parallel implementation.
* Document message index format specifiersBen Burwell2019-07-042-2/+37
|
* Crash on delete in empty folder (#213)Zach Sisco2019-07-041-0/+3
|
* Add unsubscribe commandBen Burwell2019-07-043-0/+150
| | | | | | | | | | | | | | | | The unsubscribe command, available when in a message viewer context, enables users to easily unsubscribe from mailing lists. When the command is executed, aerc looks for a List-Unsubscribe header as defined in RFC 2369. If found, aerc will attempt to present the user with a suitable interface for completing the request. Currently, mailto and http(s) URLs are supported. In the case of a HTTP(S) URL, aerc will open the link in a browser. For mailto links, a new composer tab will be opened with a message filled out according to the URL. The message is not sent automatically in order to provide the user a chance to review it first. Closes #101
* Use "open" instead of "xdg-open" on Darwin systemsBen Burwell2019-07-044-4/+25
|
* Update binds.confDrew DeVault2019-07-041-2/+2
|
* Correct default filter order in aerc.conf.inDrew DeVault2019-07-021-1/+1
|
* Revert "Remove dirs field and references to it"Drew DeVault2019-07-021-11/+10
| | | | This reverts commit 0e55637aac92e748267559b7aa91a188a17c386f.
* Remove dirs field and references to itRobert Günzler2019-06-301-10/+11
| | | | | This fixes prev/next-folder that broke after 546dfcd76dd228e0605359e9985f0b6a5672e8fa
* panic: runtime error: index out of range in handleFetchMessages (#127)Zach Sisco2019-06-291-3/+1
|
* Add new lib/dirstore to source completions fromGregory Mullen2019-06-292-4/+27
|
* Implement basic tab completion supportGregory Mullen2019-06-2947-154/+598
| | | | | Tab completion currently only works on commands. Contextual completion will be added in the future.
* Move contrib -> filtersDrew DeVault2019-06-274-3/+3
|
* Reopening mailcontent file to fix #166Stefan Rakel2019-06-271-1/+7
| | | | | | Because editors like vim use backupfiles and rename them to the original name, the file handle used can point to the wrong file. Reopening the file should fix this.
* Set the required go version for this module, aercDaniel Lublin2019-06-271-0/+2
| | | | | | This is the way to declare which compiler version a module requires to build. I read up on https://golang.org/doc/go1.12#modules
* Fix jumping around in searchDrew DeVault2019-06-261-10/+5
|
* Implement :search, :next-result, :prev-resultDrew DeVault2019-06-265-1/+149
|
* msgview/save: Use defaultSavePath if no path is providedReto Brunner2019-06-253-6/+26
|
* add DefaultSavePath configReto Brunner2019-06-251-0/+10
|
* account-wizard: look up imap and smtp server by SRV records (#100)Daniel Lublin2019-06-251-1/+42
|
* worker/imap: rig up search directory handlerDrew DeVault2019-06-241-0/+2
|
* worker/imap: implement searchDrew DeVault2019-06-242-0/+26
|
* aerc-config: [viewer] should be [compose]Issam Maghni2019-06-231-1/+1
|
* Fix Cc & Bcc handling in repliesDrew DeVault2019-06-213-7/+14
|
* Fix reply bindings in [view]Drew DeVault2019-06-191-4/+4
|
* Makefile: fix -ldflags -X invocationReto Brunner2019-06-191-3/+3
| | | | | | | | Aerc uses the go linker to add some variables like main.Prefix / main.ShareDir etc. however the go linker only considers the last -ldflags invocation it seems. This commit fixes the makefile to use only a single -ldflags invocation, which again sets the vars as expected.
* account-wizard: automatically replace imap.* with smtp.*Noah Loomans2019-06-181-1/+6
| | | | | | | | | Many email providers use the imap sub-domain for imap and the smtp sub-domain for smtp. FastMail is an example of this[1]. This is a small quality-of-life improvement which automatically replaces imap.* with smtp.* when going from the imap screen to the smtp screen in the wizard [1]: https://www.fastmail.com/help/technical/servernamesandports.html
* Insert nil check before handling prev/next messageMartin Hafskjold Thoresen2019-06-181-2/+8
| | | | | If these are called before the store is setup, `acct.Store()` returns `nil`, and we SEGFAULT in `MessageStore.nextPrev`.
* Add aerc -v to print the installed versionDrew DeVault2019-06-183-1/+28
|
* commands/msgview: add open commandRéouven Assouly2019-06-172-0/+65
|
* Make part encoding checks case insensitiveRéouven Assouly2019-06-162-6/+7
| | | | | | commands/msgview/save and commands/msgview/pipe now use case insensitive comparisons to determine if the part is encoded as base64 or quoted-printable.
* Ensure that flags are set properlyAditya Mahajan2019-06-161-2/+4
| | | | | | | | | | The current implementation has three classes of flags: - readFlag - delFlag - flaggedFlag The logic to check for them should be in parallel if branches rather than in sequential if-else ladder.
* Update tcellDrew DeVault2019-06-152-1/+3
|
* Document collecting log outputLyle Hanson2019-06-142-0/+12
| | | | | | | | | | Redirecting stdout writes log output to that file, but this wasn't easily discoverable. v2 removes changes to aerc-tutorial; I was also on the fence about that, and agree that it isn't on-topic for the tutorial. Addresses https://todo.sr.ht/~sircmpwn/aerc2/180
* imap: block until directory list is fully receivedDrew DeVault2019-06-141-0/+1
| | | | This fixes issues with INBOX mysteriously not being present at times
* Set empty message in dirlist if no folder exist.Reto Brunner2019-06-145-18/+40
|
d=95015cec56fa56f2ef97227edf06de17c65000d9'>^
81190251 ^
a2726b6a ^


81190251 ^
3bb1f124 ^
81190251 ^







88f423af ^

81190251 ^




a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^
81190251 ^
b4e9905d ^

81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^
81190251 ^
b4e9905d ^

81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^
81190251 ^
b4e9905d ^

81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^
81190251 ^
b4e9905d ^

81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^



81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^



81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^



81190251 ^
b4e9905d ^
b4e9905d ^

a2726b6a ^

b4e9905d ^
a2726b6a ^
b4e9905d ^
3bb1f124 ^
b4e9905d ^


21f0bd04 ^
81190251 ^
21f0bd04 ^
21f0bd04 ^

a2726b6a ^

21f0bd04 ^
a2726b6a ^
21f0bd04 ^
3bb1f124 ^
21f0bd04 ^
81190251 ^
21f0bd04 ^
91d4097d ^
81190251 ^
91d4097d ^
91d4097d ^

a2726b6a ^

91d4097d ^
a2726b6a ^
91d4097d ^
3bb1f124 ^
91d4097d ^
81190251 ^
91d4097d ^
bd221f6f ^
81190251 ^
bd221f6f ^
bd221f6f ^

a2726b6a ^

bd221f6f ^
a2726b6a ^
bd221f6f ^
3bb1f124 ^
bd221f6f ^
81190251 ^
bd221f6f ^

81190251 ^
bd221f6f ^
bd221f6f ^

a2726b6a ^

bd221f6f ^
a2726b6a ^
bd221f6f ^
3bb1f124 ^
bd221f6f ^
81190251 ^
bd221f6f ^
b4e9905d ^
81190251 ^
0ee6c7a6 ^
0ee6c7a6 ^

a2726b6a ^

0ee6c7a6 ^
a2726b6a ^
0ee6c7a6 ^
3bb1f124 ^
5319a03a ^


0ee6c7a6 ^
5319a03a ^
0ee6c7a6 ^
5319a03a ^
0ee6c7a6 ^
88f423af ^




0ee6c7a6 ^
81190251 ^
0ee6c7a6 ^
0ee6c7a6 ^

a2726b6a ^

0ee6c7a6 ^
a2726b6a ^
7842b0d1 ^
3bb1f124 ^
5319a03a ^


5c65599e ^
5319a03a ^
7842b0d1 ^
5319a03a ^
0ee6c7a6 ^
88f423af ^




0ee6c7a6 ^
81190251 ^
0ee6c7a6 ^
0ee6c7a6 ^

a2726b6a ^

0ee6c7a6 ^
a2726b6a ^
0ee6c7a6 ^
3bb1f124 ^
5319a03a ^


0ee6c7a6 ^
5319a03a ^
0ee6c7a6 ^
5319a03a ^
0ee6c7a6 ^
88f423af ^




7842b0d1 ^
81190251 ^
7842b0d1 ^
540d658e ^
cae2979a ^
a2726b6a ^

cae2979a ^
a2726b6a ^


cae2979a ^
3bb1f124 ^
cae2979a ^
5319a03a ^

cae2979a ^
d56f6dc3 ^
5ec2d3cf ^
88f423af ^

5ec2d3cf ^
81190251 ^
5ec2d3cf ^
5ec2d3cf ^

a2726b6a ^

5ec2d3cf ^
a2726b6a ^


5ec2d3cf ^
3bb1f124 ^
5319a03a ^


5ec2d3cf ^
5319a03a ^
5ec2d3cf ^
88f423af ^

cae2979a ^
81190251 ^
cae2979a ^
cae2979a ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

                   

                   
                   
                   
                 

                      
 
                  
                       
 
                              
                            
 

                              

                                                        
 
                                               
 

                                                                                    
                                                           
                        

 

                                                          



                                                      

                                                       



                                                   

                                                      
 
                                                  

 

                                         
 
                                                
 
                                                            







                                                                 




                                                                        




                                                           

                                      
 
                                                
 
                                                            







                                                      




                                                                   






                                                                             

                                                             
 
                                                
 
                                                            
 
                                                                 





                                                      



                                                                        
                                                                 




                                                           

                                                          
 


                                                                                                                                                                           














                                                                                   

                                                           
 


                                                                                                                                                                           
 
                                                            







                                                                            

                                                                 




                                                           

                                                          
 
                                                          
 
                                                            
 
                                                        

                         
                                                           
                        

 

                                                               
 
                                                                             
 
                                                            
 
                                                        

                         
                                                           
                        

 

                                                        
 
                                                        
 
                                                            
 
                                                        

                         
                                                           
                        

 

                                                               
 
                                                                          
 
                                                            
 
                                                        

                         
                                                           
                        

 

                                                   
 
                                                             
 
                                                            



                                                                   
                                                           
                        

 

                                                        
 
                                                              
 
                                                            



                                                                    
                                                           
                        

 

                                                       
 
                                                                 
 
                                                            



                                                                       
                                                           
                        

 

                                                                
 
                                                                 
 
                                                            


                                                                 
 
                                                           
                        

 

                                                                
 
                                                                                          
 
                                                            
 
                                                        
                         
 
                                                           
                        

 

                                                              
 
                                                                                
 
                                                            
 
                                                        
                         
 
                                                           
                        

 

                                                                 
 
                                                                   
 
                                                            
 
                                                        

                         
                                                           
                        

 

                                                                  
 
                                                                                      
 
                                                            
 
                                                        
                         
 
                                                           
                        

 

                                                   
 
                                                                     
 
                                                            


                                                                 
 
                                                     
 
                                                      
 




                                                                        
 
                                                           
                        

 

                                                 
 
                                                                
 
                                                            


                                                                 
 
                                                     
 
                                                      
 




                                                                        
 
                                                           
                        

 

                                                            
 
                                                                                     
 
                                                            


                                                                 
 
                                                     
 
                                                      
 




                                                                        
 
                                                           
                        
 
 

                                                                    
 


                                                                                                                                                                               
 
                                                            
 

                                               
 
                                                                                     
 

                                                                 
 
                                                           
                        

 

                                               
 


                                                                                                                                                                           
 
                                                            


                                               
 
                                                                            
 

                                                                                   
 
                                                           
                        
 
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

#include "xmpp/xmpp.h"

#include "ui/ui.h"
#include "ui/stub_ui.h"

#include "command/cmd_funcs.h"
#include "config/accounts.h"

#define CMD_CONNECT "/connect"

static void
test_with_connection_status(jabber_conn_status_t status)
{
    will_return(connection_get_status, status);

    expect_cons_show("You are either connected already, or a login is in process.");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, NULL);
    assert_true(result);
}

void
cmd_connect_shows_message_when_disconnecting(void** state)
{
    test_with_connection_status(JABBER_DISCONNECTING);
}

void
cmd_connect_shows_message_when_connecting(void** state)
{
    test_with_connection_status(JABBER_CONNECTING);
}

void
cmd_connect_shows_message_when_connected(void** state)
{
    test_with_connection_status(JABBER_CONNECTED);
}

void
cmd_connect_when_no_account(void** state)
{
    gchar* args[] = { "user@server.org", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(accounts_get_account, name, "user@server.org");
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_string(session_connect_with_details, jid, "user@server.org");
    expect_string(session_connect_with_details, passwd, "password");
    expect_value(session_connect_with_details, altdomain, NULL);
    expect_value(session_connect_with_details, port, 0);
    will_return(session_connect_with_details, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_fail_message(void** state)
{
    gchar* args[] = { "user@server.org", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_any(accounts_get_account, name);
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_any(session_connect_with_details, jid);
    expect_any(session_connect_with_details, passwd);
    expect_any(session_connect_with_details, altdomain);
    expect_any(session_connect_with_details, port);
    will_return(session_connect_with_details, JABBER_DISCONNECTED);

    expect_cons_show_error("Connection attempt for user@server.org failed.");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_lowercases_argument_with_no_account(void** state)
{
    gchar* args[] = { "USER@server.ORG", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(accounts_get_account, name, "USER@server.ORG");
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_string(session_connect_with_details, jid, "user@server.org");
    expect_string(session_connect_with_details, passwd, "password");
    expect_value(session_connect_with_details, altdomain, NULL);
    expect_value(session_connect_with_details, port, 0);
    will_return(session_connect_with_details, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_lowercases_argument_with_account(void** state)
{
    gchar* args[] = { "Jabber_org", NULL };
    ProfAccount* account = account_new("Jabber_org", "me@jabber.org", "password", NULL,
                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_any(accounts_get_account, name);
    will_return(accounts_get_account, account);

    expect_cons_show("Connecting with account Jabber_org as me@jabber.org");

    expect_memory(session_connect_with_account, account, account, sizeof(account));
    will_return(session_connect_with_account, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_asks_password_when_not_in_account(void** state)
{
    gchar* args[] = { "jabber_org", NULL };
    ProfAccount* account = account_new("jabber_org", "me@jabber.org", NULL, NULL,
                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_any(accounts_get_account, name);
    will_return(accounts_get_account, account);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting with account jabber_org as me@jabber.org");

    expect_any(session_connect_with_account, account);
    will_return(session_connect_with_account, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_no_server_value(void** state)
{
    gchar* args[] = { "user@server.org", "server", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_server_no_port_value(void** state)
{
    gchar* args[] = { "user@server.org", "server", "aserver", "port", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_no_port_value(void** state)
{
    gchar* args[] = { "user@server.org", "port", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_port_no_server_value(void** state)
{
    gchar* args[] = { "user@server.org", "port", "5678", "server", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_message_when_port_0(void** state)
{
    gchar* args[] = { "user@server.org", "port", "0", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_cons_show("Value 0 out of range. Must be in 1..65535.");
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_message_when_port_minus1(void** state)
{
    gchar* args[] = { "user@server.org", "port", "-1", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_cons_show("Value -1 out of range. Must be in 1..65535.");
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_message_when_port_65536(void** state)
{
    gchar* args[] = { "user@server.org", "port", "65536", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_cons_show("Value 65536 out of range. Must be in 1..65535.");
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_message_when_port_contains_chars(void** state)
{
    gchar* args[] = { "user@server.org", "port", "52f66", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_cons_show("Could not convert \"52f66\" to a number.");
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_server_provided_twice(void** state)
{
    gchar* args[] = { "user@server.org", "server", "server1", "server", "server2", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_port_provided_twice(void** state)
{
    gchar* args[] = { "user@server.org", "port", "1111", "port", "1111", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_invalid_first_property(void** state)
{
    gchar* args[] = { "user@server.org", "wrong", "server", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_usage_when_invalid_second_property(void** state)
{
    gchar* args[] = { "user@server.org", "server", "aserver", "wrong", "1234", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(cons_bad_cmd_usage, cmd, CMD_CONNECT);
    expect_cons_show("");

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_with_server_when_provided(void** state)
{
    gchar* args[] = { "user@server.org", "server", "aserver", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(accounts_get_account, name, "user@server.org");
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_string(session_connect_with_details, jid, "user@server.org");
    expect_string(session_connect_with_details, passwd, "password");
    expect_string(session_connect_with_details, altdomain, "aserver");
    expect_value(session_connect_with_details, port, 0);
    will_return(session_connect_with_details, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_with_port_when_provided(void** state)
{
    gchar* args[] = { "user@server.org", "port", "5432", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(accounts_get_account, name, "user@server.org");
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_string(session_connect_with_details, jid, "user@server.org");
    expect_string(session_connect_with_details, passwd, "password");
    expect_value(session_connect_with_details, altdomain, NULL);
    expect_value(session_connect_with_details, port, 5432);
    will_return(session_connect_with_details, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_with_server_and_port_when_provided(void** state)
{
    gchar* args[] = { "user@server.org", "port", "5432", "server", "aserver", NULL };

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_string(accounts_get_account, name, "user@server.org");
    will_return(accounts_get_account, NULL);

    will_return(ui_ask_password, strdup("password"));

    expect_cons_show("Connecting as user@server.org");

    expect_string(session_connect_with_details, jid, "user@server.org");
    expect_string(session_connect_with_details, passwd, "password");
    expect_string(session_connect_with_details, altdomain, "aserver");
    expect_value(session_connect_with_details, port, 5432);
    will_return(session_connect_with_details, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_shows_message_when_connecting_with_account(void** state)
{
    gchar* args[] = { "jabber_org", NULL };
    ProfAccount* account = account_new("jabber_org", "user@jabber.org", "password", NULL,
                                       TRUE, NULL, 0, "laptop", NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_any(accounts_get_account, name);
    will_return(accounts_get_account, account);

    expect_cons_show("Connecting with account jabber_org as user@jabber.org/laptop");

    expect_any(session_connect_with_account, account);
    will_return(session_connect_with_account, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}

void
cmd_connect_connects_with_account(void** state)
{
    gchar* args[] = { "jabber_org", NULL };
    ProfAccount* account = account_new("jabber_org", "me@jabber.org", "password", NULL,
                                       TRUE, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    will_return(connection_get_status, JABBER_DISCONNECTED);

    expect_any(accounts_get_account, name);
    will_return(accounts_get_account, account);

    expect_cons_show("Connecting with account jabber_org as me@jabber.org");

    expect_memory(session_connect_with_account, account, account, sizeof(account));
    will_return(session_connect_with_account, JABBER_CONNECTING);

    gboolean result = cmd_connect(NULL, CMD_CONNECT, args);
    assert_true(result);
}