git-send-email: improve --validate error output
[git] / t / t9001-send-email.sh
1 #!/bin/sh
2
3 test_description='git send-email'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8
9 # May be altered later in the test
10 PREREQ="PERL"
11
12 replace_variable_fields () {
13         sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
14                 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
15                 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/"
16 }
17
18 test_expect_success $PREREQ 'prepare reference tree' '
19         echo "1A quick brown fox jumps over the" >file &&
20         echo "lazy dog" >>file &&
21         git add file &&
22         GIT_AUTHOR_NAME="A" git commit -a -m "Initial."
23 '
24
25 test_expect_success $PREREQ 'Setup helper tool' '
26         write_script fake.sendmail <<-\EOF &&
27         shift
28         output=1
29         while test -f commandline$output
30         do
31                 output=$(($output+1))
32         done
33         for a
34         do
35                 echo "!$a!"
36         done >commandline$output
37         cat >"msgtxt$output"
38         EOF
39         git add fake.sendmail &&
40         GIT_AUTHOR_NAME="A" git commit -a -m "Second."
41 '
42
43 clean_fake_sendmail () {
44         rm -f commandline* msgtxt*
45 }
46
47 test_expect_success $PREREQ 'Extract patches' '
48         patches=$(git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1) &&
49         threaded_patches=$(git format-patch -o threaded -s --in-reply-to="format" HEAD^1)
50 '
51
52 # Test no confirm early to ensure remaining tests will not hang
53 test_no_confirm () {
54         rm -f no_confirm_okay
55         echo n | \
56                 GIT_SEND_EMAIL_NOTTY=1 \
57                 git send-email \
58                 --from="Example <from@example.com>" \
59                 --to=nobody@example.com \
60                 --smtp-server="$(pwd)/fake.sendmail" \
61                 $@ \
62                 $patches >stdout &&
63                 ! grep "Send this email" stdout &&
64                 >no_confirm_okay
65 }
66
67 # Exit immediately to prevent hang if a no-confirm test fails
68 check_no_confirm () {
69         if ! test -f no_confirm_okay
70         then
71                 say 'confirm test failed; skipping remaining tests to prevent hanging'
72                 PREREQ="$PREREQ,CHECK_NO_CONFIRM"
73         fi
74         return 0
75 }
76
77 test_expect_success $PREREQ 'No confirm with --suppress-cc' '
78         test_no_confirm --suppress-cc=sob &&
79         check_no_confirm
80 '
81
82
83 test_expect_success $PREREQ 'No confirm with --confirm=never' '
84         test_no_confirm --confirm=never &&
85         check_no_confirm
86 '
87
88 # leave sendemail.confirm set to never after this so that none of the
89 # remaining tests prompt unintentionally.
90 test_expect_success $PREREQ 'No confirm with sendemail.confirm=never' '
91         git config sendemail.confirm never &&
92         test_no_confirm --compose --subject=foo &&
93         check_no_confirm
94 '
95
96 test_expect_success $PREREQ 'Send patches' '
97         git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
98 '
99
100 test_expect_success $PREREQ 'setup expect' '
101         cat >expected <<-\EOF
102         !nobody@example.com!
103         !author@example.com!
104         !one@example.com!
105         !two@example.com!
106         EOF
107 '
108
109 test_expect_success $PREREQ 'Verify commandline' '
110         test_cmp expected commandline1
111 '
112
113 test_expect_success $PREREQ 'Send patches with --envelope-sender' '
114         clean_fake_sendmail &&
115         git send-email --envelope-sender="Patch Contributor <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
116 '
117
118 test_expect_success $PREREQ 'setup expect' '
119         cat >expected <<-\EOF
120         !patch@example.com!
121         !-i!
122         !nobody@example.com!
123         !author@example.com!
124         !one@example.com!
125         !two@example.com!
126         EOF
127 '
128
129 test_expect_success $PREREQ 'Verify commandline' '
130         test_cmp expected commandline1
131 '
132
133 test_expect_success $PREREQ 'Send patches with --envelope-sender=auto' '
134         clean_fake_sendmail &&
135         git send-email --envelope-sender=auto --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
136 '
137
138 test_expect_success $PREREQ 'setup expect' '
139         cat >expected <<-\EOF
140         !nobody@example.com!
141         !-i!
142         !nobody@example.com!
143         !author@example.com!
144         !one@example.com!
145         !two@example.com!
146         EOF
147 '
148
149 test_expect_success $PREREQ 'Verify commandline' '
150         test_cmp expected commandline1
151 '
152
153 test_expect_success $PREREQ 'setup expect for cc trailer' "
154 cat >expected-cc <<\EOF
155 !recipient@example.com!
156 !author@example.com!
157 !one@example.com!
158 !two@example.com!
159 !three@example.com!
160 !four@example.com!
161 !five@example.com!
162 !six@example.com!
163 EOF
164 "
165
166 test_expect_success $PREREQ 'cc trailer with various syntax' '
167         test_commit cc-trailer &&
168         test_when_finished "git reset --hard HEAD^" &&
169         git commit --amend -F - <<-EOF &&
170         Test Cc: trailers.
171
172         Cc: one@example.com
173         Cc: <two@example.com> # trailing comments are ignored
174         Cc: <three@example.com>, <not.four@example.com> one address per line
175         Cc: "Some # Body" <four@example.com> [ <also.a.comment> ]
176         Cc: five@example.com # not.six@example.com
177         Cc: six@example.com, not.seven@example.com
178         EOF
179         clean_fake_sendmail &&
180         git send-email -1 --to=recipient@example.com \
181                 --smtp-server="$(pwd)/fake.sendmail" &&
182         test_cmp expected-cc commandline1
183 '
184
185 test_expect_success $PREREQ 'setup fake get_maintainer.pl script for cc trailer' "
186         write_script expected-cc-script.sh <<-EOF
187         echo 'One Person <one@example.com> (supporter:THIS (FOO/bar))'
188         echo 'Two Person <two@example.com> (maintainer:THIS THING)'
189         echo 'Third List <three@example.com> (moderated list:THIS THING (FOO/bar))'
190         echo '<four@example.com> (moderated list:FOR THING)'
191         echo 'five@example.com (open list:FOR THING (FOO/bar))'
192         echo 'six@example.com (open list)'
193         EOF
194 "
195
196 test_expect_success $PREREQ 'cc trailer with get_maintainer.pl output' '
197         clean_fake_sendmail &&
198         git send-email -1 --to=recipient@example.com \
199                 --cc-cmd=./expected-cc-script.sh \
200                 --smtp-server="$(pwd)/fake.sendmail" &&
201         test_cmp expected-cc commandline1
202 '
203
204 test_expect_success $PREREQ 'setup expect' "
205 cat >expected-show-all-headers <<\EOF
206 0001-Second.patch
207 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
208 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
209 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
210 Dry-OK. Log says:
211 Server: relay.example.com
212 MAIL FROM:<from@example.com>
213 RCPT TO:<to@example.com>
214 RCPT TO:<cc@example.com>
215 RCPT TO:<author@example.com>
216 RCPT TO:<one@example.com>
217 RCPT TO:<two@example.com>
218 RCPT TO:<bcc@example.com>
219 From: Example <from@example.com>
220 To: to@example.com
221 Cc: cc@example.com,
222         A <author@example.com>,
223         One <one@example.com>,
224         two@example.com
225 Subject: [PATCH 1/1] Second.
226 Date: DATE-STRING
227 Message-Id: MESSAGE-ID-STRING
228 X-Mailer: X-MAILER-STRING
229 In-Reply-To: <unique-message-id@example.com>
230 References: <unique-message-id@example.com>
231 Reply-To: Reply <reply@example.com>
232 MIME-Version: 1.0
233 Content-Transfer-Encoding: 8bit
234
235 Result: OK
236 EOF
237 "
238
239 test_suppress_self () {
240         test_commit $3 &&
241         test_when_finished "git reset --hard HEAD^" &&
242
243         write_script cccmd-sed <<-EOF &&
244                 sed -n -e s/^cccmd--//p "\$1"
245         EOF
246
247         git commit --amend --author="$1 <$2>" -F - &&
248         clean_fake_sendmail &&
249         git format-patch --stdout -1 >"suppress-self-$3.patch" &&
250
251         git send-email --from="$1 <$2>" \
252                 --to=nobody@example.com \
253                 --cc-cmd=./cccmd-sed \
254                 --suppress-cc=self \
255                 --smtp-server="$(pwd)/fake.sendmail" \
256                 suppress-self-$3.patch &&
257
258         mv msgtxt1 msgtxt1-$3 &&
259         sed -e '/^$/q' msgtxt1-$3 >"msghdr1-$3" &&
260
261         (grep '^Cc:' msghdr1-$3 >"actual-no-cc-$3";
262          test_must_be_empty actual-no-cc-$3)
263 }
264
265 test_suppress_self_unquoted () {
266         test_suppress_self "$1" "$2" "unquoted-$3" <<-EOF
267                 test suppress-cc.self unquoted-$3 with name $1 email $2
268
269                 unquoted-$3
270
271                 cccmd--$1 <$2>
272
273                 Cc: $1 <$2>
274                 Signed-off-by: $1 <$2>
275         EOF
276 }
277
278 test_suppress_self_quoted () {
279         test_suppress_self "$1" "$2" "quoted-$3" <<-EOF
280                 test suppress-cc.self quoted-$3 with name $1 email $2
281
282                 quoted-$3
283
284                 cccmd--"$1" <$2>
285
286                 Cc: $1 <$2>
287                 Cc: "$1" <$2>
288                 Signed-off-by: $1 <$2>
289                 Signed-off-by: "$1" <$2>
290         EOF
291 }
292
293 test_expect_success $PREREQ 'self name is suppressed' "
294         test_suppress_self_unquoted 'A U Thor' 'author@example.com' \
295                 'self_name_suppressed'
296 "
297
298 test_expect_success $PREREQ 'self name with dot is suppressed' "
299         test_suppress_self_quoted 'A U. Thor' 'author@example.com' \
300                 'self_name_dot_suppressed'
301 "
302
303 test_expect_success $PREREQ 'non-ascii self name is suppressed' "
304         test_suppress_self_quoted 'Füñný Nâmé' 'odd_?=mail@example.com' \
305                 'non_ascii_self_suppressed'
306 "
307
308 # This name is long enough to force format-patch to split it into multiple
309 # encoded-words, assuming it uses UTF-8 with the "Q" encoding.
310 test_expect_success $PREREQ 'long non-ascii self name is suppressed' "
311         test_suppress_self_quoted 'Ƒüñníęř €. Nâṁé' 'odd_?=mail@example.com' \
312                 'long_non_ascii_self_suppressed'
313 "
314
315 test_expect_success $PREREQ 'sanitized self name is suppressed' "
316         test_suppress_self_unquoted '\"A U. Thor\"' 'author@example.com' \
317                 'self_name_sanitized_suppressed'
318 "
319
320 test_expect_success $PREREQ 'Show all headers' '
321         git send-email \
322                 --dry-run \
323                 --suppress-cc=sob \
324                 --from="Example <from@example.com>" \
325                 --reply-to="Reply <reply@example.com>" \
326                 --to=to@example.com \
327                 --cc=cc@example.com \
328                 --bcc=bcc@example.com \
329                 --in-reply-to="<unique-message-id@example.com>" \
330                 --smtp-server relay.example.com \
331                 $patches | replace_variable_fields \
332                 >actual-show-all-headers &&
333         test_cmp expected-show-all-headers actual-show-all-headers
334 '
335
336 test_expect_success $PREREQ 'Prompting works' '
337         clean_fake_sendmail &&
338         (echo "to@example.com" &&
339          echo ""
340         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
341                 --smtp-server="$(pwd)/fake.sendmail" \
342                 $patches \
343                 2>errors &&
344                 grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
345                 grep "^To: to@example.com\$" msgtxt1
346 '
347
348 test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' '
349         clean_fake_sendmail &&
350         (sane_unset GIT_AUTHOR_NAME &&
351         sane_unset GIT_AUTHOR_EMAIL &&
352         sane_unset GIT_COMMITTER_NAME &&
353         sane_unset GIT_COMMITTER_EMAIL &&
354         GIT_SEND_EMAIL_NOTTY=1 git send-email \
355                 --smtp-server="$(pwd)/fake.sendmail" \
356                 --to=to@example.com \
357                 $patches </dev/null 2>errors
358         )
359 '
360
361 test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' '
362         clean_fake_sendmail &&
363         (sane_unset GIT_AUTHOR_NAME &&
364         sane_unset GIT_AUTHOR_EMAIL &&
365         sane_unset GIT_COMMITTER_NAME &&
366         sane_unset GIT_COMMITTER_EMAIL &&
367         GIT_SEND_EMAIL_NOTTY=1 && export GIT_SEND_EMAIL_NOTTY &&
368         test_must_fail git send-email \
369                 --smtp-server="$(pwd)/fake.sendmail" \
370                 --to=to@example.com \
371                 $patches </dev/null 2>errors &&
372         test_i18ngrep "tell me who you are" errors
373         )
374 '
375
376 test_expect_success $PREREQ 'setup tocmd and cccmd scripts' '
377         write_script tocmd-sed <<-\EOF &&
378         sed -n -e "s/^tocmd--//p" "$1"
379         EOF
380         write_script cccmd-sed <<-\EOF
381         sed -n -e "s/^cccmd--//p" "$1"
382         EOF
383 '
384
385 test_expect_success $PREREQ 'tocmd works' '
386         clean_fake_sendmail &&
387         cp $patches tocmd.patch &&
388         echo tocmd--tocmd@example.com >>tocmd.patch &&
389         git send-email \
390                 --from="Example <nobody@example.com>" \
391                 --to-cmd=./tocmd-sed \
392                 --smtp-server="$(pwd)/fake.sendmail" \
393                 tocmd.patch \
394                 &&
395         grep "^To: tocmd@example.com" msgtxt1
396 '
397
398 test_expect_success $PREREQ 'cccmd works' '
399         clean_fake_sendmail &&
400         cp $patches cccmd.patch &&
401         echo "cccmd--  cccmd@example.com" >>cccmd.patch &&
402         git send-email \
403                 --from="Example <nobody@example.com>" \
404                 --to=nobody@example.com \
405                 --cc-cmd=./cccmd-sed \
406                 --smtp-server="$(pwd)/fake.sendmail" \
407                 cccmd.patch \
408                 &&
409         grep "^ cccmd@example.com" msgtxt1
410 '
411
412 test_expect_success $PREREQ 'reject long lines' '
413         z8=zzzzzzzz &&
414         z64=$z8$z8$z8$z8$z8$z8$z8$z8 &&
415         z512=$z64$z64$z64$z64$z64$z64$z64$z64 &&
416         clean_fake_sendmail &&
417         cp $patches longline.patch &&
418         cat >>longline.patch <<-EOF &&
419         $z512$z512
420         not a long line
421         $z512$z512
422         EOF
423         test_must_fail git send-email \
424                 --from="Example <nobody@example.com>" \
425                 --to=nobody@example.com \
426                 --smtp-server="$(pwd)/fake.sendmail" \
427                 --transfer-encoding=8bit \
428                 $patches longline.patch \
429                 2>actual &&
430         cat >expect <<-\EOF &&
431         fatal: longline.patch:35 is longer than 998 characters
432         warning: no patches were sent
433         EOF
434         test_cmp expect actual
435 '
436
437 test_expect_success $PREREQ 'no patch was sent' '
438         ! test -e commandline1
439 '
440
441 test_expect_success $PREREQ 'Author From: in message body' '
442         clean_fake_sendmail &&
443         git send-email \
444                 --from="Example <nobody@example.com>" \
445                 --to=nobody@example.com \
446                 --smtp-server="$(pwd)/fake.sendmail" \
447                 $patches &&
448         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
449         grep "From: A <author@example.com>" msgbody1
450 '
451
452 test_expect_success $PREREQ 'Author From: not in message body' '
453         clean_fake_sendmail &&
454         git send-email \
455                 --from="A <author@example.com>" \
456                 --to=nobody@example.com \
457                 --smtp-server="$(pwd)/fake.sendmail" \
458                 $patches &&
459         sed "1,/^\$/d" <msgtxt1 >msgbody1 &&
460         ! grep "From: A <author@example.com>" msgbody1
461 '
462
463 test_expect_success $PREREQ 'allow long lines with --no-validate' '
464         git send-email \
465                 --from="Example <nobody@example.com>" \
466                 --to=nobody@example.com \
467                 --smtp-server="$(pwd)/fake.sendmail" \
468                 --no-validate \
469                 $patches longline.patch \
470                 2>errors
471 '
472
473 test_expect_success $PREREQ 'short lines with auto encoding are 8bit' '
474         clean_fake_sendmail &&
475         git send-email \
476                 --from="A <author@example.com>" \
477                 --to=nobody@example.com \
478                 --smtp-server="$(pwd)/fake.sendmail" \
479                 --transfer-encoding=auto \
480                 $patches &&
481         grep "Content-Transfer-Encoding: 8bit" msgtxt1
482 '
483
484 test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable' '
485         clean_fake_sendmail &&
486         git send-email \
487                 --from="Example <nobody@example.com>" \
488                 --to=nobody@example.com \
489                 --smtp-server="$(pwd)/fake.sendmail" \
490                 --transfer-encoding=auto \
491                 --no-validate \
492                 longline.patch &&
493         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
494 '
495
496 test_expect_success $PREREQ 'carriage returns with auto encoding are quoted-printable' '
497         clean_fake_sendmail &&
498         cp $patches cr.patch &&
499         printf "this is a line\r\n" >>cr.patch &&
500         git send-email \
501                 --from="Example <nobody@example.com>" \
502                 --to=nobody@example.com \
503                 --smtp-server="$(pwd)/fake.sendmail" \
504                 --transfer-encoding=auto \
505                 --no-validate \
506                 cr.patch &&
507         grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
508 '
509
510 for enc in auto quoted-printable base64
511 do
512         test_expect_success $PREREQ "--validate passes with encoding $enc" '
513                 git send-email \
514                         --from="Example <nobody@example.com>" \
515                         --to=nobody@example.com \
516                         --smtp-server="$(pwd)/fake.sendmail" \
517                         --transfer-encoding=$enc \
518                         --validate \
519                         $patches longline.patch
520         '
521
522 done
523
524 test_expect_success $PREREQ "--validate respects relative core.hooksPath path" '
525         clean_fake_sendmail &&
526         mkdir my-hooks &&
527         test_when_finished "rm my-hooks.ran" &&
528         write_script my-hooks/sendemail-validate <<-\EOF &&
529         >my-hooks.ran
530         exit 1
531         EOF
532         test_config core.hooksPath "my-hooks" &&
533         test_must_fail git send-email \
534                 --from="Example <nobody@example.com>" \
535                 --to=nobody@example.com \
536                 --smtp-server="$(pwd)/fake.sendmail" \
537                 --validate \
538                 longline.patch 2>actual &&
539         test_path_is_file my-hooks.ran &&
540         cat >expect <<-EOF &&
541         fatal: longline.patch: rejected by sendemail-validate hook
542         fatal: command '"'"'$(pwd)/my-hooks/sendemail-validate'"'"' died with exit code 1
543         warning: no patches were sent
544         EOF
545         test_cmp expect actual
546 '
547
548 test_expect_success $PREREQ "--validate respects absolute core.hooksPath path" '
549         hooks_path="$(pwd)/my-hooks" &&
550         test_config core.hooksPath "$hooks_path" &&
551         test_when_finished "rm my-hooks.ran" &&
552         test_must_fail git send-email \
553                 --from="Example <nobody@example.com>" \
554                 --to=nobody@example.com \
555                 --smtp-server="$(pwd)/fake.sendmail" \
556                 --validate \
557                 longline.patch 2>actual &&
558         test_path_is_file my-hooks.ran &&
559         cat >expect <<-EOF &&
560         fatal: longline.patch: rejected by sendemail-validate hook
561         fatal: command '"'"'$hooks_path/sendemail-validate'"'"' died with exit code 1
562         warning: no patches were sent
563         EOF
564         test_cmp expect actual
565 '
566
567 for enc in 7bit 8bit quoted-printable base64
568 do
569         test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" '
570                 clean_fake_sendmail &&
571                 git send-email \
572                         --from="Example <nobody@example.com>" \
573                         --to=nobody@example.com \
574                         --smtp-server="$(pwd)/fake.sendmail" \
575                         --transfer-encoding=$enc \
576                         $patches &&
577                 grep "Content-Transfer-Encoding: $enc" msgtxt1
578         '
579 done
580
581 test_expect_success $PREREQ 'Invalid In-Reply-To' '
582         clean_fake_sendmail &&
583         git send-email \
584                 --from="Example <nobody@example.com>" \
585                 --to=nobody@example.com \
586                 --in-reply-to=" " \
587                 --smtp-server="$(pwd)/fake.sendmail" \
588                 $patches \
589                 2>errors &&
590         ! grep "^In-Reply-To: < *>" msgtxt1
591 '
592
593 test_expect_success $PREREQ 'Valid In-Reply-To when prompting' '
594         clean_fake_sendmail &&
595         (echo "From Example <from@example.com>" &&
596          echo "To Example <to@example.com>" &&
597          echo ""
598         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
599                 --smtp-server="$(pwd)/fake.sendmail" \
600                 $patches 2>errors &&
601         ! grep "^In-Reply-To: < *>" msgtxt1
602 '
603
604 test_expect_success $PREREQ 'In-Reply-To without --chain-reply-to' '
605         clean_fake_sendmail &&
606         echo "<unique-message-id@example.com>" >expect &&
607         git send-email \
608                 --from="Example <nobody@example.com>" \
609                 --to=nobody@example.com \
610                 --no-chain-reply-to \
611                 --in-reply-to="$(cat expect)" \
612                 --smtp-server="$(pwd)/fake.sendmail" \
613                 $patches $patches $patches \
614                 2>errors &&
615         # The first message is a reply to --in-reply-to
616         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
617         test_cmp expect actual &&
618         # Second and subsequent messages are replies to the first one
619         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
620         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
621         test_cmp expect actual &&
622         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
623         test_cmp expect actual
624 '
625
626 test_expect_success $PREREQ 'In-Reply-To with --chain-reply-to' '
627         clean_fake_sendmail &&
628         echo "<unique-message-id@example.com>" >expect &&
629         git send-email \
630                 --from="Example <nobody@example.com>" \
631                 --to=nobody@example.com \
632                 --chain-reply-to \
633                 --in-reply-to="$(cat expect)" \
634                 --smtp-server="$(pwd)/fake.sendmail" \
635                 $patches $patches $patches \
636                 2>errors &&
637         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual &&
638         test_cmp expect actual &&
639         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect &&
640         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual &&
641         test_cmp expect actual &&
642         sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt2 >expect &&
643         sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual &&
644         test_cmp expect actual
645 '
646
647 test_expect_success $PREREQ 'setup fake editor' '
648         write_script fake-editor <<-\EOF
649         echo fake edit >>"$1"
650         EOF
651 '
652
653 test_set_editor "$(pwd)/fake-editor"
654
655 test_expect_success $PREREQ '--compose works' '
656         clean_fake_sendmail &&
657         git send-email \
658         --compose --subject foo \
659         --from="Example <nobody@example.com>" \
660         --to=nobody@example.com \
661         --smtp-server="$(pwd)/fake.sendmail" \
662         $patches \
663         2>errors
664 '
665
666 test_expect_success $PREREQ 'first message is compose text' '
667         grep "^fake edit" msgtxt1
668 '
669
670 test_expect_success $PREREQ 'second message is patch' '
671         grep "Subject:.*Second" msgtxt2
672 '
673
674 test_expect_success $PREREQ 'setup expect' "
675 cat >expected-suppress-sob <<\EOF
676 0001-Second.patch
677 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
678 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
679 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
680 Dry-OK. Log says:
681 Server: relay.example.com
682 MAIL FROM:<from@example.com>
683 RCPT TO:<to@example.com>
684 RCPT TO:<cc@example.com>
685 RCPT TO:<author@example.com>
686 RCPT TO:<one@example.com>
687 RCPT TO:<two@example.com>
688 From: Example <from@example.com>
689 To: to@example.com
690 Cc: cc@example.com,
691         A <author@example.com>,
692         One <one@example.com>,
693         two@example.com
694 Subject: [PATCH 1/1] Second.
695 Date: DATE-STRING
696 Message-Id: MESSAGE-ID-STRING
697 X-Mailer: X-MAILER-STRING
698 MIME-Version: 1.0
699 Content-Transfer-Encoding: 8bit
700
701 Result: OK
702 EOF
703 "
704
705 test_suppression () {
706         git send-email \
707                 --dry-run \
708                 --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
709                 --from="Example <from@example.com>" \
710                 --to=to@example.com \
711                 --smtp-server relay.example.com \
712                 $patches | replace_variable_fields \
713                 >actual-suppress-$1${2+"-$2"} &&
714         test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
715 }
716
717 test_expect_success $PREREQ 'sendemail.cc set' '
718         git config sendemail.cc cc@example.com &&
719         test_suppression sob
720 '
721
722 test_expect_success $PREREQ 'setup expect' "
723 cat >expected-suppress-sob <<\EOF
724 0001-Second.patch
725 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
726 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
727 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
728 Dry-OK. Log says:
729 Server: relay.example.com
730 MAIL FROM:<from@example.com>
731 RCPT TO:<to@example.com>
732 RCPT TO:<author@example.com>
733 RCPT TO:<one@example.com>
734 RCPT TO:<two@example.com>
735 From: Example <from@example.com>
736 To: to@example.com
737 Cc: A <author@example.com>,
738         One <one@example.com>,
739         two@example.com
740 Subject: [PATCH 1/1] Second.
741 Date: DATE-STRING
742 Message-Id: MESSAGE-ID-STRING
743 X-Mailer: X-MAILER-STRING
744 MIME-Version: 1.0
745 Content-Transfer-Encoding: 8bit
746
747 Result: OK
748 EOF
749 "
750
751 test_expect_success $PREREQ 'sendemail.cc unset' '
752         git config --unset sendemail.cc &&
753         test_suppression sob
754 '
755
756 test_expect_success $PREREQ 'setup expect' "
757 cat >expected-suppress-cccmd <<\EOF
758 0001-Second.patch
759 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
760 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
761 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
762 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
763 Dry-OK. Log says:
764 Server: relay.example.com
765 MAIL FROM:<from@example.com>
766 RCPT TO:<to@example.com>
767 RCPT TO:<author@example.com>
768 RCPT TO:<one@example.com>
769 RCPT TO:<two@example.com>
770 RCPT TO:<committer@example.com>
771 From: Example <from@example.com>
772 To: to@example.com
773 Cc: A <author@example.com>,
774         One <one@example.com>,
775         two@example.com,
776         C O Mitter <committer@example.com>
777 Subject: [PATCH 1/1] Second.
778 Date: DATE-STRING
779 Message-Id: MESSAGE-ID-STRING
780 X-Mailer: X-MAILER-STRING
781 MIME-Version: 1.0
782 Content-Transfer-Encoding: 8bit
783
784 Result: OK
785 EOF
786 "
787
788 test_expect_success $PREREQ 'sendemail.cccmd' '
789         write_script cccmd <<-\EOF &&
790         echo cc-cmd@example.com
791         EOF
792         git config sendemail.cccmd ./cccmd &&
793         test_suppression cccmd
794 '
795
796 test_expect_success $PREREQ 'setup expect' '
797 cat >expected-suppress-all <<\EOF
798 0001-Second.patch
799 Dry-OK. Log says:
800 Server: relay.example.com
801 MAIL FROM:<from@example.com>
802 RCPT TO:<to@example.com>
803 From: Example <from@example.com>
804 To: to@example.com
805 Subject: [PATCH 1/1] Second.
806 Date: DATE-STRING
807 Message-Id: MESSAGE-ID-STRING
808 X-Mailer: X-MAILER-STRING
809 MIME-Version: 1.0
810 Content-Transfer-Encoding: 8bit
811
812 Result: OK
813 EOF
814 '
815
816 test_expect_success $PREREQ '--suppress-cc=all' '
817         test_suppression all
818 '
819
820 test_expect_success $PREREQ 'setup expect' "
821 cat >expected-suppress-body <<\EOF
822 0001-Second.patch
823 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
824 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
825 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
826 (cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
827 Dry-OK. Log says:
828 Server: relay.example.com
829 MAIL FROM:<from@example.com>
830 RCPT TO:<to@example.com>
831 RCPT TO:<author@example.com>
832 RCPT TO:<one@example.com>
833 RCPT TO:<two@example.com>
834 RCPT TO:<cc-cmd@example.com>
835 From: Example <from@example.com>
836 To: to@example.com
837 Cc: A <author@example.com>,
838         One <one@example.com>,
839         two@example.com,
840         cc-cmd@example.com
841 Subject: [PATCH 1/1] Second.
842 Date: DATE-STRING
843 Message-Id: MESSAGE-ID-STRING
844 X-Mailer: X-MAILER-STRING
845 MIME-Version: 1.0
846 Content-Transfer-Encoding: 8bit
847
848 Result: OK
849 EOF
850 "
851
852 test_expect_success $PREREQ '--suppress-cc=body' '
853         test_suppression body
854 '
855
856 test_expect_success $PREREQ 'setup expect' "
857 cat >expected-suppress-body-cccmd <<\EOF
858 0001-Second.patch
859 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
860 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
861 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
862 Dry-OK. Log says:
863 Server: relay.example.com
864 MAIL FROM:<from@example.com>
865 RCPT TO:<to@example.com>
866 RCPT TO:<author@example.com>
867 RCPT TO:<one@example.com>
868 RCPT TO:<two@example.com>
869 From: Example <from@example.com>
870 To: to@example.com
871 Cc: A <author@example.com>,
872         One <one@example.com>,
873         two@example.com
874 Subject: [PATCH 1/1] Second.
875 Date: DATE-STRING
876 Message-Id: MESSAGE-ID-STRING
877 X-Mailer: X-MAILER-STRING
878 MIME-Version: 1.0
879 Content-Transfer-Encoding: 8bit
880
881 Result: OK
882 EOF
883 "
884
885 test_expect_success $PREREQ '--suppress-cc=body --suppress-cc=cccmd' '
886         test_suppression body cccmd
887 '
888
889 test_expect_success $PREREQ 'setup expect' "
890 cat >expected-suppress-sob <<\EOF
891 0001-Second.patch
892 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
893 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
894 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
895 Dry-OK. Log says:
896 Server: relay.example.com
897 MAIL FROM:<from@example.com>
898 RCPT TO:<to@example.com>
899 RCPT TO:<author@example.com>
900 RCPT TO:<one@example.com>
901 RCPT TO:<two@example.com>
902 From: Example <from@example.com>
903 To: to@example.com
904 Cc: A <author@example.com>,
905         One <one@example.com>,
906         two@example.com
907 Subject: [PATCH 1/1] Second.
908 Date: DATE-STRING
909 Message-Id: MESSAGE-ID-STRING
910 X-Mailer: X-MAILER-STRING
911 MIME-Version: 1.0
912 Content-Transfer-Encoding: 8bit
913
914 Result: OK
915 EOF
916 "
917
918 test_expect_success $PREREQ '--suppress-cc=sob' '
919         test_might_fail git config --unset sendemail.cccmd &&
920         test_suppression sob
921 '
922
923 test_expect_success $PREREQ 'setup expect' "
924 cat >expected-suppress-bodycc <<\EOF
925 0001-Second.patch
926 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
927 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
928 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
929 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
930 Dry-OK. Log says:
931 Server: relay.example.com
932 MAIL FROM:<from@example.com>
933 RCPT TO:<to@example.com>
934 RCPT TO:<author@example.com>
935 RCPT TO:<one@example.com>
936 RCPT TO:<two@example.com>
937 RCPT TO:<committer@example.com>
938 From: Example <from@example.com>
939 To: to@example.com
940 Cc: A <author@example.com>,
941         One <one@example.com>,
942         two@example.com,
943         C O Mitter <committer@example.com>
944 Subject: [PATCH 1/1] Second.
945 Date: DATE-STRING
946 Message-Id: MESSAGE-ID-STRING
947 X-Mailer: X-MAILER-STRING
948 MIME-Version: 1.0
949 Content-Transfer-Encoding: 8bit
950
951 Result: OK
952 EOF
953 "
954
955 test_expect_success $PREREQ '--suppress-cc=bodycc' '
956         test_suppression bodycc
957 '
958
959 test_expect_success $PREREQ 'setup expect' "
960 cat >expected-suppress-cc <<\EOF
961 0001-Second.patch
962 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
963 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
964 Dry-OK. Log says:
965 Server: relay.example.com
966 MAIL FROM:<from@example.com>
967 RCPT TO:<to@example.com>
968 RCPT TO:<author@example.com>
969 RCPT TO:<committer@example.com>
970 From: Example <from@example.com>
971 To: to@example.com
972 Cc: A <author@example.com>,
973         C O Mitter <committer@example.com>
974 Subject: [PATCH 1/1] Second.
975 Date: DATE-STRING
976 Message-Id: MESSAGE-ID-STRING
977 X-Mailer: X-MAILER-STRING
978 MIME-Version: 1.0
979 Content-Transfer-Encoding: 8bit
980
981 Result: OK
982 EOF
983 "
984
985 test_expect_success $PREREQ '--suppress-cc=cc' '
986         test_suppression cc
987 '
988
989 test_confirm () {
990         echo y | \
991                 GIT_SEND_EMAIL_NOTTY=1 \
992                 git send-email \
993                 --from="Example <nobody@example.com>" \
994                 --to=nobody@example.com \
995                 --smtp-server="$(pwd)/fake.sendmail" \
996                 $@ $patches >stdout &&
997         grep "Send this email" stdout
998 }
999
1000 test_expect_success $PREREQ '--confirm=always' '
1001         test_confirm --confirm=always --suppress-cc=all
1002 '
1003
1004 test_expect_success $PREREQ '--confirm=auto' '
1005         test_confirm --confirm=auto
1006 '
1007
1008 test_expect_success $PREREQ '--confirm=cc' '
1009         test_confirm --confirm=cc
1010 '
1011
1012 test_expect_success $PREREQ '--confirm=compose' '
1013         test_confirm --confirm=compose --compose
1014 '
1015
1016 test_expect_success $PREREQ 'confirm by default (due to cc)' '
1017         test_when_finished git config sendemail.confirm never &&
1018         git config --unset sendemail.confirm &&
1019         test_confirm
1020 '
1021
1022 test_expect_success $PREREQ 'confirm by default (due to --compose)' '
1023         test_when_finished git config sendemail.confirm never &&
1024         git config --unset sendemail.confirm &&
1025         test_confirm --suppress-cc=all --compose
1026 '
1027
1028 test_expect_success $PREREQ 'confirm detects EOF (inform assumes y)' '
1029         test_when_finished git config sendemail.confirm never &&
1030         git config --unset sendemail.confirm &&
1031         rm -fr outdir &&
1032         git format-patch -2 -o outdir &&
1033         GIT_SEND_EMAIL_NOTTY=1 \
1034                 git send-email \
1035                         --from="Example <nobody@example.com>" \
1036                         --to=nobody@example.com \
1037                         --smtp-server="$(pwd)/fake.sendmail" \
1038                         outdir/*.patch </dev/null
1039 '
1040
1041 test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' '
1042         test_when_finished git config sendemail.confirm never &&
1043         git config sendemail.confirm auto &&
1044         GIT_SEND_EMAIL_NOTTY=1 &&
1045         export GIT_SEND_EMAIL_NOTTY &&
1046                 test_must_fail git send-email \
1047                         --from="Example <nobody@example.com>" \
1048                         --to=nobody@example.com \
1049                         --smtp-server="$(pwd)/fake.sendmail" \
1050                         $patches </dev/null
1051 '
1052
1053 test_expect_success $PREREQ 'confirm does not loop forever' '
1054         test_when_finished git config sendemail.confirm never &&
1055         git config sendemail.confirm auto &&
1056         GIT_SEND_EMAIL_NOTTY=1 &&
1057         export GIT_SEND_EMAIL_NOTTY &&
1058                 yes "bogus" | test_must_fail git send-email \
1059                         --from="Example <nobody@example.com>" \
1060                         --to=nobody@example.com \
1061                         --smtp-server="$(pwd)/fake.sendmail" \
1062                         $patches
1063 '
1064
1065 test_expect_success $PREREQ 'utf8 Cc is rfc2047 encoded' '
1066         clean_fake_sendmail &&
1067         rm -fr outdir &&
1068         git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
1069         git send-email \
1070         --from="Example <nobody@example.com>" \
1071         --to=nobody@example.com \
1072         --smtp-server="$(pwd)/fake.sendmail" \
1073         outdir/*.patch &&
1074         grep "^ " msgtxt1 |
1075         grep "=?UTF-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
1076 '
1077
1078 test_expect_success $PREREQ '--compose adds MIME for utf8 body' '
1079         clean_fake_sendmail &&
1080         write_script fake-editor-utf8 <<-\EOF &&
1081         echo "utf8 body: àéìöú" >>"$1"
1082         EOF
1083         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1084         git send-email \
1085                 --compose --subject foo \
1086                 --from="Example <nobody@example.com>" \
1087                 --to=nobody@example.com \
1088                 --smtp-server="$(pwd)/fake.sendmail" \
1089                 $patches &&
1090         grep "^utf8 body" msgtxt1 &&
1091         grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1092 '
1093
1094 test_expect_success $PREREQ '--compose respects user mime type' '
1095         clean_fake_sendmail &&
1096         write_script fake-editor-utf8-mime <<-\EOF &&
1097         cat >"$1" <<-\EOM
1098         MIME-Version: 1.0
1099         Content-Type: text/plain; charset=iso-8859-1
1100         Content-Transfer-Encoding: 8bit
1101         Subject: foo
1102
1103         utf8 body: àéìöú
1104         EOM
1105         EOF
1106         GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
1107         git send-email \
1108                 --compose --subject foo \
1109                 --from="Example <nobody@example.com>" \
1110                 --to=nobody@example.com \
1111                 --smtp-server="$(pwd)/fake.sendmail" \
1112                 $patches &&
1113         grep "^utf8 body" msgtxt1 &&
1114         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
1115         ! grep "^Content-Type: text/plain; charset=UTF-8" msgtxt1
1116 '
1117
1118 test_expect_success $PREREQ '--compose adds MIME for utf8 subject' '
1119         clean_fake_sendmail &&
1120         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1121         git send-email \
1122                 --compose --subject utf8-sübjëct \
1123                 --from="Example <nobody@example.com>" \
1124                 --to=nobody@example.com \
1125                 --smtp-server="$(pwd)/fake.sendmail" \
1126                 $patches &&
1127         grep "^fake edit" msgtxt1 &&
1128         grep "^Subject: =?UTF-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1129 '
1130
1131 test_expect_success $PREREQ 'utf8 author is correctly passed on' '
1132         clean_fake_sendmail &&
1133         test_commit weird_author &&
1134         test_when_finished "git reset --hard HEAD^" &&
1135         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1136         git format-patch --stdout -1 >funny_name.patch &&
1137         git send-email --from="Example <nobody@example.com>" \
1138                 --to=nobody@example.com \
1139                 --smtp-server="$(pwd)/fake.sendmail" \
1140                 funny_name.patch &&
1141         grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1
1142 '
1143
1144 test_expect_success $PREREQ 'utf8 sender is not duplicated' '
1145         clean_fake_sendmail &&
1146         test_commit weird_sender &&
1147         test_when_finished "git reset --hard HEAD^" &&
1148         git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" &&
1149         git format-patch --stdout -1 >funny_name.patch &&
1150         git send-email --from="Füñný Nâmé <odd_?=mail@example.com>" \
1151                 --to=nobody@example.com \
1152                 --smtp-server="$(pwd)/fake.sendmail" \
1153                 funny_name.patch &&
1154         grep "^From: " msgtxt1 >msgfrom &&
1155         test_line_count = 1 msgfrom
1156 '
1157
1158 test_expect_success $PREREQ 'sendemail.composeencoding works' '
1159         clean_fake_sendmail &&
1160         git config sendemail.composeencoding iso-8859-1 &&
1161         write_script fake-editor-utf8 <<-\EOF &&
1162         echo "utf8 body: àéìöú" >>"$1"
1163         EOF
1164         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1165         git send-email \
1166                 --compose --subject foo \
1167                 --from="Example <nobody@example.com>" \
1168                 --to=nobody@example.com \
1169                 --smtp-server="$(pwd)/fake.sendmail" \
1170                 $patches &&
1171         grep "^utf8 body" msgtxt1 &&
1172         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1173 '
1174
1175 test_expect_success $PREREQ '--compose-encoding works' '
1176         clean_fake_sendmail &&
1177         write_script fake-editor-utf8 <<-\EOF &&
1178         echo "utf8 body: àéìöú" >>"$1"
1179         EOF
1180         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1181         git send-email \
1182                 --compose-encoding iso-8859-1 \
1183                 --compose --subject foo \
1184                 --from="Example <nobody@example.com>" \
1185                 --to=nobody@example.com \
1186                 --smtp-server="$(pwd)/fake.sendmail" \
1187                 $patches &&
1188         grep "^utf8 body" msgtxt1 &&
1189         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
1190 '
1191
1192 test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
1193         clean_fake_sendmail &&
1194         git config sendemail.composeencoding iso-8859-1 &&
1195         write_script fake-editor-utf8 <<-\EOF &&
1196         echo "utf8 body: àéìöú" >>"$1"
1197         EOF
1198         GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
1199         git send-email \
1200                 --compose-encoding iso-8859-2 \
1201                 --compose --subject foo \
1202                 --from="Example <nobody@example.com>" \
1203                 --to=nobody@example.com \
1204                 --smtp-server="$(pwd)/fake.sendmail" \
1205                 $patches &&
1206         grep "^utf8 body" msgtxt1 &&
1207         grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
1208 '
1209
1210 test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
1211         clean_fake_sendmail &&
1212         GIT_EDITOR="\"$(pwd)/fake-editor\"" \
1213         git send-email \
1214                 --compose-encoding iso-8859-2 \
1215                 --compose --subject utf8-sübjëct \
1216                 --from="Example <nobody@example.com>" \
1217                 --to=nobody@example.com \
1218                 --smtp-server="$(pwd)/fake.sendmail" \
1219                 $patches &&
1220         grep "^fake edit" msgtxt1 &&
1221         grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
1222 '
1223
1224 test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
1225         echo main >main &&
1226         git add main &&
1227         git commit -m"add main" &&
1228         test_must_fail git send-email --dry-run main 2>errors &&
1229         grep disambiguate errors
1230 '
1231
1232 test_expect_success $PREREQ 'feed two files' '
1233         rm -fr outdir &&
1234         git format-patch -2 -o outdir &&
1235         git send-email \
1236                 --dry-run \
1237                 --from="Example <nobody@example.com>" \
1238                 --to=nobody@example.com \
1239                 outdir/000?-*.patch 2>errors >out &&
1240         grep "^Subject: " out >subjects &&
1241         test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
1242         test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add main"
1243 '
1244
1245 test_expect_success $PREREQ 'in-reply-to but no threading' '
1246         git send-email \
1247                 --dry-run \
1248                 --from="Example <nobody@example.com>" \
1249                 --to=nobody@example.com \
1250                 --in-reply-to="<in-reply-id@example.com>" \
1251                 --no-thread \
1252                 $patches >out &&
1253         grep "In-Reply-To: <in-reply-id@example.com>" out
1254 '
1255
1256 test_expect_success $PREREQ 'no in-reply-to and no threading' '
1257         git send-email \
1258                 --dry-run \
1259                 --from="Example <nobody@example.com>" \
1260                 --to=nobody@example.com \
1261                 --no-thread \
1262                 $patches >stdout &&
1263         ! grep "In-Reply-To: " stdout
1264 '
1265
1266 test_expect_success $PREREQ 'threading but no chain-reply-to' '
1267         git send-email \
1268                 --dry-run \
1269                 --from="Example <nobody@example.com>" \
1270                 --to=nobody@example.com \
1271                 --thread \
1272                 --no-chain-reply-to \
1273                 $patches $patches >stdout &&
1274         grep "In-Reply-To: " stdout
1275 '
1276
1277 test_expect_success $PREREQ 'override in-reply-to if no threading' '
1278         git send-email \
1279                 --dry-run \
1280                 --from="Example <nobody@example.com>" \
1281                 --to=nobody@example.com \
1282                 --no-thread \
1283                 --in-reply-to="override" \
1284                 $threaded_patches >stdout &&
1285         grep "In-Reply-To: <override>" stdout
1286 '
1287
1288 test_expect_success $PREREQ 'sendemail.to works' '
1289         git config --replace-all sendemail.to "Somebody <somebody@ex.com>" &&
1290         git send-email \
1291                 --dry-run \
1292                 --from="Example <nobody@example.com>" \
1293                 $patches >stdout &&
1294         grep "To: Somebody <somebody@ex.com>" stdout
1295 '
1296
1297 test_expect_success $PREREQ 'setup sendemail.identity' '
1298         git config --replace-all sendemail.to "default@example.com" &&
1299         git config --replace-all sendemail.isp.to "isp@example.com" &&
1300         git config --replace-all sendemail.cloud.to "cloud@example.com"
1301 '
1302
1303 test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' '
1304         git -c sendemail.identity=cloud send-email \
1305                 --dry-run \
1306                 --from="nobody@example.com" \
1307                 $patches >stdout &&
1308         grep "To: cloud@example.com" stdout
1309 '
1310
1311 test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' '
1312         git -c sendemail.identity=cloud send-email \
1313                 --identity=isp \
1314                 --dry-run \
1315                 --from="nobody@example.com" \
1316                 $patches >stdout &&
1317         grep "To: isp@example.com" stdout
1318 '
1319
1320 test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' '
1321         git -c sendemail.identity=cloud send-email \
1322                 --no-identity \
1323                 --dry-run \
1324                 --from="nobody@example.com" \
1325                 $patches >stdout &&
1326         grep "To: default@example.com" stdout
1327 '
1328
1329 test_expect_success $PREREQ 'sendemail.identity: bool identity variable existence overrides' '
1330         git -c sendemail.identity=cloud \
1331                 -c sendemail.xmailer=true \
1332                 -c sendemail.cloud.xmailer=false \
1333                 send-email \
1334                 --dry-run \
1335                 --from="nobody@example.com" \
1336                 $patches >stdout &&
1337         grep "To: cloud@example.com" stdout &&
1338         ! grep "X-Mailer" stdout
1339 '
1340
1341 test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' '
1342         git -c sendemail.identity=cloud \
1343                 -c sendemail.xmailer=false \
1344                 send-email \
1345                 --dry-run \
1346                 --from="nobody@example.com" \
1347                 $patches >stdout &&
1348         grep "To: cloud@example.com" stdout &&
1349         ! grep "X-Mailer" stdout
1350 '
1351
1352 test_expect_success $PREREQ '--no-to overrides sendemail.to' '
1353         git send-email \
1354                 --dry-run \
1355                 --from="Example <nobody@example.com>" \
1356                 --no-to \
1357                 --to=nobody@example.com \
1358                 $patches >stdout &&
1359         grep "To: nobody@example.com" stdout &&
1360         ! grep "To: Somebody <somebody@ex.com>" stdout
1361 '
1362
1363 test_expect_success $PREREQ 'sendemail.cc works' '
1364         git config --replace-all sendemail.cc "Somebody <somebody@ex.com>" &&
1365         git send-email \
1366                 --dry-run \
1367                 --from="Example <nobody@example.com>" \
1368                 --to=nobody@example.com \
1369                 $patches >stdout &&
1370         grep "Cc: Somebody <somebody@ex.com>" stdout
1371 '
1372
1373 test_expect_success $PREREQ '--no-cc overrides sendemail.cc' '
1374         git send-email \
1375                 --dry-run \
1376                 --from="Example <nobody@example.com>" \
1377                 --no-cc \
1378                 --cc=bodies@example.com \
1379                 --to=nobody@example.com \
1380                 $patches >stdout &&
1381         grep "Cc: bodies@example.com" stdout &&
1382         ! grep "Cc: Somebody <somebody@ex.com>" stdout
1383 '
1384
1385 test_expect_success $PREREQ 'sendemail.bcc works' '
1386         git config --replace-all sendemail.bcc "Other <other@ex.com>" &&
1387         git send-email \
1388                 --dry-run \
1389                 --from="Example <nobody@example.com>" \
1390                 --to=nobody@example.com \
1391                 --smtp-server relay.example.com \
1392                 $patches >stdout &&
1393         grep "RCPT TO:<other@ex.com>" stdout
1394 '
1395
1396 test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' '
1397         git send-email \
1398                 --dry-run \
1399                 --from="Example <nobody@example.com>" \
1400                 --no-bcc \
1401                 --bcc=bodies@example.com \
1402                 --to=nobody@example.com \
1403                 --smtp-server relay.example.com \
1404                 $patches >stdout &&
1405         grep "RCPT TO:<bodies@example.com>" stdout &&
1406         ! grep "RCPT TO:<other@ex.com>" stdout
1407 '
1408
1409 test_expect_success $PREREQ 'patches To headers are used by default' '
1410         patch=$(git format-patch -1 --to="bodies@example.com") &&
1411         test_when_finished "rm $patch" &&
1412         git send-email \
1413                 --dry-run \
1414                 --from="Example <nobody@example.com>" \
1415                 --smtp-server relay.example.com \
1416                 $patch >stdout &&
1417         grep "RCPT TO:<bodies@example.com>" stdout
1418 '
1419
1420 test_expect_success $PREREQ 'patches To headers are appended to' '
1421         patch=$(git format-patch -1 --to="bodies@example.com") &&
1422         test_when_finished "rm $patch" &&
1423         git send-email \
1424                 --dry-run \
1425                 --from="Example <nobody@example.com>" \
1426                 --to=nobody@example.com \
1427                 --smtp-server relay.example.com \
1428                 $patch >stdout &&
1429         grep "RCPT TO:<bodies@example.com>" stdout &&
1430         grep "RCPT TO:<nobody@example.com>" stdout
1431 '
1432
1433 test_expect_success $PREREQ 'To headers from files reset each patch' '
1434         patch1=$(git format-patch -1 --to="bodies@example.com") &&
1435         patch2=$(git format-patch -1 --to="other@example.com" HEAD~) &&
1436         test_when_finished "rm $patch1 && rm $patch2" &&
1437         git send-email \
1438                 --dry-run \
1439                 --from="Example <nobody@example.com>" \
1440                 --to="nobody@example.com" \
1441                 --smtp-server relay.example.com \
1442                 $patch1 $patch2 >stdout &&
1443         test $(grep -c "RCPT TO:<bodies@example.com>" stdout) = 1 &&
1444         test $(grep -c "RCPT TO:<nobody@example.com>" stdout) = 2 &&
1445         test $(grep -c "RCPT TO:<other@example.com>" stdout) = 1
1446 '
1447
1448 test_expect_success $PREREQ 'setup expect' '
1449 cat >email-using-8bit <<\EOF
1450 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1451 Message-Id: <bogus-message-id@example.com>
1452 From: author@example.com
1453 Date: Sat, 12 Jun 2010 15:53:58 +0200
1454 Subject: subject goes here
1455
1456 Dieser deutsche Text enthält einen Umlaut!
1457 EOF
1458 '
1459
1460 test_expect_success $PREREQ 'setup expect' '
1461         echo "Subject: subject goes here" >expected
1462 '
1463
1464 test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
1465         clean_fake_sendmail &&
1466         echo bogus |
1467         git send-email --from=author@example.com --to=nobody@example.com \
1468                         --smtp-server="$(pwd)/fake.sendmail" \
1469                         --8bit-encoding=UTF-8 \
1470                         email-using-8bit >stdout &&
1471         grep "Subject" msgtxt1 >actual &&
1472         test_cmp expected actual
1473 '
1474
1475 test_expect_success $PREREQ 'setup expect' '
1476         cat >content-type-decl <<-\EOF
1477         MIME-Version: 1.0
1478         Content-Type: text/plain; charset=UTF-8
1479         Content-Transfer-Encoding: 8bit
1480         EOF
1481 '
1482
1483 test_expect_success $PREREQ 'asks about and fixes 8bit encodings' '
1484         clean_fake_sendmail &&
1485         echo |
1486         git send-email --from=author@example.com --to=nobody@example.com \
1487                         --smtp-server="$(pwd)/fake.sendmail" \
1488                         email-using-8bit >stdout &&
1489         grep "do not declare a Content-Transfer-Encoding" stdout &&
1490         grep email-using-8bit stdout &&
1491         grep "Which 8bit encoding" stdout &&
1492         egrep "Content|MIME" msgtxt1 >actual &&
1493         test_cmp content-type-decl actual
1494 '
1495
1496 test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
1497         clean_fake_sendmail &&
1498         git config sendemail.assume8bitEncoding UTF-8 &&
1499         echo bogus |
1500         git send-email --from=author@example.com --to=nobody@example.com \
1501                         --smtp-server="$(pwd)/fake.sendmail" \
1502                         email-using-8bit >stdout &&
1503         egrep "Content|MIME" msgtxt1 >actual &&
1504         test_cmp content-type-decl actual
1505 '
1506
1507 test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
1508         clean_fake_sendmail &&
1509         git config sendemail.assume8bitEncoding "bogus too" &&
1510         echo bogus |
1511         git send-email --from=author@example.com --to=nobody@example.com \
1512                         --smtp-server="$(pwd)/fake.sendmail" \
1513                         --8bit-encoding=UTF-8 \
1514                         email-using-8bit >stdout &&
1515         egrep "Content|MIME" msgtxt1 >actual &&
1516         test_cmp content-type-decl actual
1517 '
1518
1519 test_expect_success $PREREQ 'setup expect' '
1520         cat >email-using-8bit <<-\EOF
1521         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1522         Message-Id: <bogus-message-id@example.com>
1523         From: author@example.com
1524         Date: Sat, 12 Jun 2010 15:53:58 +0200
1525         Subject: Dieser Betreff enthält auch einen Umlaut!
1526
1527         Nothing to see here.
1528         EOF
1529 '
1530
1531 test_expect_success $PREREQ 'setup expect' '
1532         cat >expected <<-\EOF
1533         Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?=
1534         EOF
1535 '
1536
1537 test_expect_success $PREREQ '--8bit-encoding also treats subject' '
1538         clean_fake_sendmail &&
1539         echo bogus |
1540         git send-email --from=author@example.com --to=nobody@example.com \
1541                         --smtp-server="$(pwd)/fake.sendmail" \
1542                         --8bit-encoding=UTF-8 \
1543                         email-using-8bit >stdout &&
1544         grep "Subject" msgtxt1 >actual &&
1545         test_cmp expected actual
1546 '
1547
1548 test_expect_success $PREREQ 'setup expect' '
1549         cat >email-using-8bit <<-\EOF
1550         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1551         Message-Id: <bogus-message-id@example.com>
1552         From: A U Thor <author@example.com>
1553         Date: Sat, 12 Jun 2010 15:53:58 +0200
1554         Content-Type: text/plain; charset=UTF-8
1555         Subject: Nothing to see here.
1556
1557         Dieser Betreff enthält auch einen Umlaut!
1558         EOF
1559 '
1560
1561 test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' '
1562         clean_fake_sendmail &&
1563         test_must_fail git -c sendemail.transferEncoding=8bit \
1564                 send-email \
1565                 --transfer-encoding=7bit \
1566                 --smtp-server="$(pwd)/fake.sendmail" \
1567                 email-using-8bit \
1568                 2>errors >out &&
1569         grep "cannot send message as 7bit" errors &&
1570         test -z "$(ls msgtxt*)"
1571 '
1572
1573 test_expect_success $PREREQ 'sendemail.transferEncoding via config' '
1574         clean_fake_sendmail &&
1575         test_must_fail git -c sendemail.transferEncoding=7bit \
1576                 send-email \
1577                 --smtp-server="$(pwd)/fake.sendmail" \
1578                 email-using-8bit \
1579                 2>errors >out &&
1580         grep "cannot send message as 7bit" errors &&
1581         test -z "$(ls msgtxt*)"
1582 '
1583
1584 test_expect_success $PREREQ 'sendemail.transferEncoding via cli' '
1585         clean_fake_sendmail &&
1586         test_must_fail git send-email \
1587                 --transfer-encoding=7bit \
1588                 --smtp-server="$(pwd)/fake.sendmail" \
1589                 email-using-8bit \
1590                 2>errors >out &&
1591         grep "cannot send message as 7bit" errors &&
1592         test -z "$(ls msgtxt*)"
1593 '
1594
1595 test_expect_success $PREREQ 'setup expect' '
1596         cat >expected <<-\EOF
1597         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1598         EOF
1599 '
1600
1601 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=quoted-printable' '
1602         clean_fake_sendmail &&
1603         git send-email \
1604                 --transfer-encoding=quoted-printable \
1605                 --smtp-server="$(pwd)/fake.sendmail" \
1606                 email-using-8bit \
1607                 2>errors >out &&
1608         sed "1,/^$/d" msgtxt1 >actual &&
1609         test_cmp expected actual
1610 '
1611
1612 test_expect_success $PREREQ 'setup expect' '
1613         cat >expected <<-\EOF
1614         RGllc2VyIEJldHJlZmYgZW50aMOkbHQgYXVjaCBlaW5lbiBVbWxhdXQhCg==
1615         EOF
1616 '
1617
1618 test_expect_success $PREREQ '8-bit and sendemail.transferencoding=base64' '
1619         clean_fake_sendmail &&
1620         git send-email \
1621                 --transfer-encoding=base64 \
1622                 --smtp-server="$(pwd)/fake.sendmail" \
1623                 email-using-8bit \
1624                 2>errors >out &&
1625         sed "1,/^$/d" msgtxt1 >actual &&
1626         test_cmp expected actual
1627 '
1628
1629 test_expect_success $PREREQ 'setup expect' '
1630         cat >email-using-qp <<-\EOF
1631         From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1632         Message-Id: <bogus-message-id@example.com>
1633         From: A U Thor <author@example.com>
1634         Date: Sat, 12 Jun 2010 15:53:58 +0200
1635         MIME-Version: 1.0
1636         Content-Transfer-Encoding: quoted-printable
1637         Content-Type: text/plain; charset=UTF-8
1638         Subject: Nothing to see here.
1639
1640         Dieser Betreff enth=C3=A4lt auch einen Umlaut!
1641         EOF
1642 '
1643
1644 test_expect_success $PREREQ 'convert from quoted-printable to base64' '
1645         clean_fake_sendmail &&
1646         git send-email \
1647                 --transfer-encoding=base64 \
1648                 --smtp-server="$(pwd)/fake.sendmail" \
1649                 email-using-qp \
1650                 2>errors >out &&
1651         sed "1,/^$/d" msgtxt1 >actual &&
1652         test_cmp expected actual
1653 '
1654
1655 test_expect_success $PREREQ 'setup expect' "
1656 tr -d '\\015' | tr '%' '\\015' >email-using-crlf <<EOF
1657 From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001
1658 Message-Id: <bogus-message-id@example.com>
1659 From: A U Thor <author@example.com>
1660 Date: Sat, 12 Jun 2010 15:53:58 +0200
1661 Content-Type: text/plain; charset=UTF-8
1662 Subject: Nothing to see here.
1663
1664 Look, I have a CRLF and an = sign!%
1665 EOF
1666 "
1667
1668 test_expect_success $PREREQ 'setup expect' '
1669         cat >expected <<-\EOF
1670         Look, I have a CRLF and an =3D sign!=0D
1671         EOF
1672 '
1673
1674 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=quoted-printable' '
1675         clean_fake_sendmail &&
1676         git send-email \
1677                 --transfer-encoding=quoted-printable \
1678                 --smtp-server="$(pwd)/fake.sendmail" \
1679                 email-using-crlf \
1680                 2>errors >out &&
1681         sed "1,/^$/d" msgtxt1 >actual &&
1682         test_cmp expected actual
1683 '
1684
1685 test_expect_success $PREREQ 'setup expect' '
1686         cat >expected <<-\EOF
1687         TG9vaywgSSBoYXZlIGEgQ1JMRiBhbmQgYW4gPSBzaWduIQ0K
1688         EOF
1689 '
1690
1691 test_expect_success $PREREQ 'CRLF and sendemail.transferencoding=base64' '
1692         clean_fake_sendmail &&
1693         git send-email \
1694                 --transfer-encoding=base64 \
1695                 --smtp-server="$(pwd)/fake.sendmail" \
1696                 email-using-crlf \
1697                 2>errors >out &&
1698         sed "1,/^$/d" msgtxt1 >actual &&
1699         test_cmp expected actual
1700 '
1701
1702
1703 # Note that the patches in this test are deliberately out of order; we
1704 # want to make sure it works even if the cover-letter is not in the
1705 # first mail.
1706 test_expect_success $PREREQ 'refusing to send cover letter template' '
1707         clean_fake_sendmail &&
1708         rm -fr outdir &&
1709         git format-patch --cover-letter -2 -o outdir &&
1710         test_must_fail git send-email \
1711                 --from="Example <nobody@example.com>" \
1712                 --to=nobody@example.com \
1713                 --smtp-server="$(pwd)/fake.sendmail" \
1714                 outdir/0002-*.patch \
1715                 outdir/0000-*.patch \
1716                 outdir/0001-*.patch \
1717                 2>errors >out &&
1718         grep "SUBJECT HERE" errors &&
1719         test -z "$(ls msgtxt*)"
1720 '
1721
1722 test_expect_success $PREREQ '--force sends cover letter template anyway' '
1723         clean_fake_sendmail &&
1724         rm -fr outdir &&
1725         git format-patch --cover-letter -2 -o outdir &&
1726         git send-email \
1727                 --force \
1728                 --from="Example <nobody@example.com>" \
1729                 --to=nobody@example.com \
1730                 --smtp-server="$(pwd)/fake.sendmail" \
1731                 outdir/0002-*.patch \
1732                 outdir/0000-*.patch \
1733                 outdir/0001-*.patch \
1734                 2>errors >out &&
1735         ! grep "SUBJECT HERE" errors &&
1736         test -n "$(ls msgtxt*)"
1737 '
1738
1739 test_cover_addresses () {
1740         header="$1"
1741         shift
1742         clean_fake_sendmail &&
1743         rm -fr outdir &&
1744         git format-patch --cover-letter -2 -o outdir &&
1745         cover=$(echo outdir/0000-*.patch) &&
1746         mv $cover cover-to-edit.patch &&
1747         perl -pe "s/^From:/$header: extra\@address.com\nFrom:/" cover-to-edit.patch >"$cover" &&
1748         git send-email \
1749                 --force \
1750                 --from="Example <nobody@example.com>" \
1751                 --no-to --no-cc \
1752                 "$@" \
1753                 --smtp-server="$(pwd)/fake.sendmail" \
1754                 outdir/0000-*.patch \
1755                 outdir/0001-*.patch \
1756                 outdir/0002-*.patch \
1757                 2>errors >out &&
1758         grep "^$header: extra@address.com" msgtxt1 >to1 &&
1759         grep "^$header: extra@address.com" msgtxt2 >to2 &&
1760         grep "^$header: extra@address.com" msgtxt3 >to3 &&
1761         test_line_count = 1 to1 &&
1762         test_line_count = 1 to2 &&
1763         test_line_count = 1 to3
1764 }
1765
1766 test_expect_success $PREREQ 'to-cover adds To to all mail' '
1767         test_cover_addresses "To" --to-cover
1768 '
1769
1770 test_expect_success $PREREQ 'cc-cover adds Cc to all mail' '
1771         test_cover_addresses "Cc" --cc-cover
1772 '
1773
1774 test_expect_success $PREREQ 'tocover adds To to all mail' '
1775         test_config sendemail.tocover true &&
1776         test_cover_addresses "To"
1777 '
1778
1779 test_expect_success $PREREQ 'cccover adds Cc to all mail' '
1780         test_config sendemail.cccover true &&
1781         test_cover_addresses "Cc"
1782 '
1783
1784 test_expect_success $PREREQ 'escaped quotes in sendemail.aliasfiletype=mutt' '
1785         clean_fake_sendmail &&
1786         echo "alias sbd \\\"Dot U. Sir\\\" <somebody@example.org>" >.mutt &&
1787         git config --replace-all sendemail.aliasesfile "$(pwd)/.mutt" &&
1788         git config sendemail.aliasfiletype mutt &&
1789         git send-email \
1790                 --from="Example <nobody@example.com>" \
1791                 --to=sbd \
1792                 --smtp-server="$(pwd)/fake.sendmail" \
1793                 outdir/0001-*.patch \
1794                 2>errors >out &&
1795         grep "^!somebody@example\.org!$" commandline1 &&
1796         grep -F "To: \"Dot U. Sir\" <somebody@example.org>" out
1797 '
1798
1799 test_expect_success $PREREQ 'sendemail.aliasfiletype=mailrc' '
1800         clean_fake_sendmail &&
1801         echo "alias sbd  somebody@example.org" >.mailrc &&
1802         git config --replace-all sendemail.aliasesfile "$(pwd)/.mailrc" &&
1803         git config sendemail.aliasfiletype mailrc &&
1804         git send-email \
1805                 --from="Example <nobody@example.com>" \
1806                 --to=sbd \
1807                 --smtp-server="$(pwd)/fake.sendmail" \
1808                 outdir/0001-*.patch \
1809                 2>errors >out &&
1810         grep "^!somebody@example\.org!$" commandline1
1811 '
1812
1813 test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' '
1814         clean_fake_sendmail &&
1815         echo "alias sbd  someone@example.org" >"$HOME/.mailrc" &&
1816         git config --replace-all sendemail.aliasesfile "~/.mailrc" &&
1817         git config sendemail.aliasfiletype mailrc &&
1818         git send-email \
1819                 --from="Example <nobody@example.com>" \
1820                 --to=sbd \
1821                 --smtp-server="$(pwd)/fake.sendmail" \
1822                 outdir/0001-*.patch \
1823                 2>errors >out &&
1824         grep "^!someone@example\.org!$" commandline1
1825 '
1826
1827 test_dump_aliases () {
1828         msg="$1" && shift &&
1829         filetype="$1" && shift &&
1830         printf '%s\n' "$@" >expect &&
1831         cat >.tmp-email-aliases &&
1832
1833         test_expect_success $PREREQ "$msg" '
1834                 clean_fake_sendmail && rm -fr outdir &&
1835                 git config --replace-all sendemail.aliasesfile \
1836                         "$(pwd)/.tmp-email-aliases" &&
1837                 git config sendemail.aliasfiletype "$filetype" &&
1838                 git send-email --dump-aliases 2>errors >actual &&
1839                 test_cmp expect actual
1840         '
1841 }
1842
1843 test_dump_aliases '--dump-aliases sendmail format' \
1844         'sendmail' \
1845         'abgroup' \
1846         'alice' \
1847         'bcgrp' \
1848         'bob' \
1849         'chloe' <<-\EOF
1850         alice: Alice W Land <awol@example.com>
1851         bob: Robert Bobbyton <bob@example.com>
1852         chloe: chloe@example.com
1853         abgroup: alice, bob
1854         bcgrp: bob, chloe, Other <o@example.com>
1855         EOF
1856
1857 test_dump_aliases '--dump-aliases mutt format' \
1858         'mutt' \
1859         'alice' \
1860         'bob' \
1861         'chloe' \
1862         'donald' <<-\EOF
1863         alias alice Alice W Land <awol@example.com>
1864         alias donald Donald C Carlton <donc@example.com>
1865         alias bob Robert Bobbyton <bob@example.com>
1866         alias chloe chloe@example.com
1867         EOF
1868
1869 test_dump_aliases '--dump-aliases mailrc format' \
1870         'mailrc' \
1871         'alice' \
1872         'bob' \
1873         'chloe' \
1874         'eve' <<-\EOF
1875         alias alice   Alice W Land <awol@example.com>
1876         alias eve     Eve <eve@example.com>
1877         alias bob     Robert Bobbyton <bob@example.com>
1878         alias chloe   chloe@example.com
1879         EOF
1880
1881 test_dump_aliases '--dump-aliases pine format' \
1882         'pine' \
1883         'alice' \
1884         'bob' \
1885         'chloe' \
1886         'eve' <<-\EOF
1887         alice   Alice W Land    <awol@example.com>
1888         eve     Eve     <eve@example.com>
1889         bob     Robert  Bobbyton <bob@example.com>
1890         chloe           chloe@example.com
1891         EOF
1892
1893 test_dump_aliases '--dump-aliases gnus format' \
1894         'gnus' \
1895         'alice' \
1896         'bob' \
1897         'chloe' \
1898         'eve' <<-\EOF
1899         (define-mail-alias "alice" "awol@example.com")
1900         (define-mail-alias "eve" "eve@example.com")
1901         (define-mail-alias "bob" "bob@example.com")
1902         (define-mail-alias "chloe" "chloe@example.com")
1903         EOF
1904
1905 test_expect_success '--dump-aliases must be used alone' '
1906         test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting
1907 '
1908
1909 test_expect_success $PREREQ 'aliases and sendemail.identity' '
1910         test_must_fail git \
1911                 -c sendemail.identity=cloud \
1912                 -c sendemail.aliasesfile=default-aliases \
1913                 -c sendemail.cloud.aliasesfile=cloud-aliases \
1914                 send-email -1 2>stderr &&
1915         test_i18ngrep "cloud-aliases" stderr
1916 '
1917
1918 test_sendmail_aliases () {
1919         msg="$1" && shift &&
1920         expect="$@" &&
1921         cat >.tmp-email-aliases &&
1922
1923         test_expect_success $PREREQ "$msg" '
1924                 clean_fake_sendmail && rm -fr outdir &&
1925                 git format-patch -1 -o outdir &&
1926                 git config --replace-all sendemail.aliasesfile \
1927                         "$(pwd)/.tmp-email-aliases" &&
1928                 git config sendemail.aliasfiletype sendmail &&
1929                 git send-email \
1930                         --from="Example <nobody@example.com>" \
1931                         --to=alice --to=bcgrp \
1932                         --smtp-server="$(pwd)/fake.sendmail" \
1933                         outdir/0001-*.patch \
1934                         2>errors >out &&
1935                 for i in $expect
1936                 do
1937                         grep "^!$i!$" commandline1 || return 1
1938                 done
1939         '
1940 }
1941
1942 test_sendmail_aliases 'sendemail.aliasfiletype=sendmail' \
1943         'awol@example\.com' \
1944         'bob@example\.com' \
1945         'chloe@example\.com' \
1946         'o@example\.com' <<-\EOF
1947         alice: Alice W Land <awol@example.com>
1948         bob: Robert Bobbyton <bob@example.com>
1949         # this is a comment
1950            # this is also a comment
1951         chloe: chloe@example.com
1952         abgroup: alice, bob
1953         bcgrp: bob, chloe, Other <o@example.com>
1954         EOF
1955
1956 test_sendmail_aliases 'sendmail aliases line folding' \
1957         alice1 \
1958         bob1 bob2 \
1959         chuck1 chuck2 \
1960         darla1 darla2 darla3 \
1961         elton1 elton2 elton3 \
1962         fred1 fred2 \
1963         greg1 <<-\EOF
1964         alice: alice1
1965         bob: bob1,\
1966         bob2
1967         chuck: chuck1,
1968             chuck2
1969         darla: darla1,\
1970         darla2,
1971             darla3
1972         elton: elton1,
1973             elton2,\
1974         elton3
1975         fred: fred1,\
1976             fred2
1977         greg: greg1
1978         bcgrp: bob, chuck, darla, elton, fred, greg
1979         EOF
1980
1981 test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \
1982         alice1 bob1 <<-\EOF
1983             alice: alice1
1984         bcgrp: bob1\
1985         EOF
1986
1987 test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\EOF
1988         EOF
1989
1990 test_expect_success $PREREQ 'alias support in To header' '
1991         clean_fake_sendmail &&
1992         echo "alias sbd  someone@example.org" >.mailrc &&
1993         test_config sendemail.aliasesfile ".mailrc" &&
1994         test_config sendemail.aliasfiletype mailrc &&
1995         git format-patch --stdout -1 --to=sbd >aliased.patch &&
1996         git send-email \
1997                 --from="Example <nobody@example.com>" \
1998                 --smtp-server="$(pwd)/fake.sendmail" \
1999                 aliased.patch \
2000                 2>errors >out &&
2001         grep "^!someone@example\.org!$" commandline1
2002 '
2003
2004 test_expect_success $PREREQ 'alias support in Cc header' '
2005         clean_fake_sendmail &&
2006         echo "alias sbd  someone@example.org" >.mailrc &&
2007         test_config sendemail.aliasesfile ".mailrc" &&
2008         test_config sendemail.aliasfiletype mailrc &&
2009         git format-patch --stdout -1 --cc=sbd >aliased.patch &&
2010         git send-email \
2011                 --from="Example <nobody@example.com>" \
2012                 --smtp-server="$(pwd)/fake.sendmail" \
2013                 aliased.patch \
2014                 2>errors >out &&
2015         grep "^!someone@example\.org!$" commandline1
2016 '
2017
2018 test_expect_success $PREREQ 'tocmd works with aliases' '
2019         clean_fake_sendmail &&
2020         echo "alias sbd  someone@example.org" >.mailrc &&
2021         test_config sendemail.aliasesfile ".mailrc" &&
2022         test_config sendemail.aliasfiletype mailrc &&
2023         git format-patch --stdout -1 >tocmd.patch &&
2024         echo tocmd--sbd >>tocmd.patch &&
2025         git send-email \
2026                 --from="Example <nobody@example.com>" \
2027                 --to-cmd=./tocmd-sed \
2028                 --smtp-server="$(pwd)/fake.sendmail" \
2029                 tocmd.patch \
2030                 2>errors >out &&
2031         grep "^!someone@example\.org!$" commandline1
2032 '
2033
2034 test_expect_success $PREREQ 'cccmd works with aliases' '
2035         clean_fake_sendmail &&
2036         echo "alias sbd  someone@example.org" >.mailrc &&
2037         test_config sendemail.aliasesfile ".mailrc" &&
2038         test_config sendemail.aliasfiletype mailrc &&
2039         git format-patch --stdout -1 >cccmd.patch &&
2040         echo cccmd--sbd >>cccmd.patch &&
2041         git send-email \
2042                 --from="Example <nobody@example.com>" \
2043                 --cc-cmd=./cccmd-sed \
2044                 --smtp-server="$(pwd)/fake.sendmail" \
2045                 cccmd.patch \
2046                 2>errors >out &&
2047         grep "^!someone@example\.org!$" commandline1
2048 '
2049
2050 do_xmailer_test () {
2051         expected=$1 params=$2 &&
2052         git format-patch -1 &&
2053         git send-email \
2054                 --from="Example <nobody@example.com>" \
2055                 --to=someone@example.com \
2056                 --smtp-server="$(pwd)/fake.sendmail" \
2057                 $params \
2058                 0001-*.patch \
2059                 2>errors >out &&
2060         { grep '^X-Mailer:' out || :; } >mailer &&
2061         test_line_count = $expected mailer
2062 }
2063
2064 test_expect_success $PREREQ '--[no-]xmailer without any configuration' '
2065         do_xmailer_test 1 "--xmailer" &&
2066         do_xmailer_test 0 "--no-xmailer"
2067 '
2068
2069 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=true' '
2070         test_config sendemail.xmailer true &&
2071         do_xmailer_test 1 "" &&
2072         do_xmailer_test 0 "--no-xmailer" &&
2073         do_xmailer_test 1 "--xmailer"
2074 '
2075
2076 test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
2077         test_config sendemail.xmailer false &&
2078         do_xmailer_test 0 "" &&
2079         do_xmailer_test 0 "--no-xmailer" &&
2080         do_xmailer_test 1 "--xmailer"
2081 '
2082
2083 test_expect_success $PREREQ 'setup expected-list' '
2084         git send-email \
2085         --dry-run \
2086         --from="Example <from@example.com>" \
2087         --to="To 1 <to1@example.com>" \
2088         --to="to2@example.com" \
2089         --to="to3@example.com" \
2090         --cc="Cc 1 <cc1@example.com>" \
2091         --cc="Cc2 <cc2@example.com>" \
2092         --bcc="bcc1@example.com" \
2093         --bcc="bcc2@example.com" \
2094         0001-add-main.patch | replace_variable_fields \
2095         >expected-list
2096 '
2097
2098 test_expect_success $PREREQ 'use email list in --cc --to and --bcc' '
2099         git send-email \
2100         --dry-run \
2101         --from="Example <from@example.com>" \
2102         --to="To 1 <to1@example.com>, to2@example.com" \
2103         --to="to3@example.com" \
2104         --cc="Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>" \
2105         --bcc="bcc1@example.com, bcc2@example.com" \
2106         0001-add-main.patch | replace_variable_fields \
2107         >actual-list &&
2108         test_cmp expected-list actual-list
2109 '
2110
2111 test_expect_success $PREREQ 'aliases work with email list' '
2112         echo "alias to2 to2@example.com" >.mutt &&
2113         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2114         test_config sendemail.aliasesfile ".mutt" &&
2115         test_config sendemail.aliasfiletype mutt &&
2116         git send-email \
2117         --dry-run \
2118         --from="Example <from@example.com>" \
2119         --to="To 1 <to1@example.com>, to2, to3@example.com" \
2120         --cc="cc1, Cc2 <cc2@example.com>" \
2121         --bcc="bcc1@example.com, bcc2@example.com" \
2122         0001-add-main.patch | replace_variable_fields \
2123         >actual-list &&
2124         test_cmp expected-list actual-list
2125 '
2126
2127 test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
2128         echo "alias to2 to2@example.com" >.mutt &&
2129         echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt &&
2130         test_config sendemail.aliasesfile ".mutt" &&
2131         test_config sendemail.aliasfiletype mutt &&
2132         TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) &&
2133         TO2=$(echo "QZto2" | qz_to_tab_space) &&
2134         CC1=$(echo "cc1" | append_cr) &&
2135         BCC1=$(echo " bcc1@example.com Q" | q_to_nul) &&
2136         git send-email \
2137         --dry-run \
2138         --from="        Example <from@example.com>" \
2139         --to="$TO1" \
2140         --to="$TO2" \
2141         --to="  to3@example.com   " \
2142         --cc="$CC1" \
2143         --cc="Cc2 <cc2@example.com>" \
2144         --bcc="$BCC1" \
2145         --bcc="bcc2@example.com" \
2146         0001-add-main.patch | replace_variable_fields \
2147         >actual-list &&
2148         test_cmp expected-list actual-list
2149 '
2150
2151 test_expect_success $PREREQ 'invoke hook' '
2152         mkdir -p .git/hooks &&
2153
2154         write_script .git/hooks/sendemail-validate <<-\EOF &&
2155         # test that we have the correct environment variable, pwd, and
2156         # argument
2157         case "$GIT_DIR" in
2158         *.git)
2159                 true
2160                 ;;
2161         *)
2162                 false
2163                 ;;
2164         esac &&
2165         test -f 0001-add-main.patch &&
2166         grep "add main" "$1"
2167         EOF
2168
2169         mkdir subdir &&
2170         (
2171                 # Test that it works even if we are not at the root of the
2172                 # working tree
2173                 cd subdir &&
2174                 git send-email \
2175                         --from="Example <nobody@example.com>" \
2176                         --to=nobody@example.com \
2177                         --smtp-server="$(pwd)/../fake.sendmail" \
2178                         ../0001-add-main.patch &&
2179
2180                 # Verify error message when a patch is rejected by the hook
2181                 sed -e "s/add main/x/" ../0001-add-main.patch >../another.patch &&
2182                 test_must_fail git send-email \
2183                         --from="Example <nobody@example.com>" \
2184                         --to=nobody@example.com \
2185                         --smtp-server="$(pwd)/../fake.sendmail" \
2186                         ../another.patch 2>err &&
2187                 test_i18ngrep "rejected by sendemail-validate hook" err
2188         )
2189 '
2190
2191 test_expect_success $PREREQ 'test that send-email works outside a repo' '
2192         nongit git send-email \
2193                 --from="Example <nobody@example.com>" \
2194                 --to=nobody@example.com \
2195                 --smtp-server="$(pwd)/fake.sendmail" \
2196                 "$(pwd)/0001-add-main.patch"
2197 '
2198
2199 test_expect_success $PREREQ 'test that sendmail config is rejected' '
2200         test_config sendmail.program sendmail &&
2201         test_must_fail git send-email \
2202                 --from="Example <nobody@example.com>" \
2203                 --to=nobody@example.com \
2204                 --smtp-server="$(pwd)/fake.sendmail" \
2205                 HEAD^ 2>err &&
2206         test_i18ngrep "found configuration options for '"'"sendmail"'"'" err
2207 '
2208
2209 test_expect_success $PREREQ 'test that sendmail config rejection is specific' '
2210         test_config resendmail.program sendmail &&
2211         git send-email \
2212                 --from="Example <nobody@example.com>" \
2213                 --to=nobody@example.com \
2214                 --smtp-server="$(pwd)/fake.sendmail" \
2215                 HEAD^
2216 '
2217
2218 test_expect_success $PREREQ 'test forbidSendmailVariables behavior override' '
2219         test_config sendmail.program sendmail &&
2220         test_config sendemail.forbidSendmailVariables false &&
2221         git send-email \
2222                 --from="Example <nobody@example.com>" \
2223                 --to=nobody@example.com \
2224                 --smtp-server="$(pwd)/fake.sendmail" \
2225                 HEAD^
2226 '
2227
2228 test_done