Code

Merge branch 'ms/http-auth'
[git.git] / t / t9001-send-email.sh
1 #!/bin/sh
3 test_description='git send-email'
4 . ./test-lib.sh
6 PROG='git send-email'
7 test_expect_success \
8     'prepare reference tree' \
9     'echo "1A quick brown fox jumps over the" >file &&
10      echo "lazy dog" >>file &&
11      git add file &&
12      GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
14 test_expect_success \
15     'Setup helper tool' \
16     '(echo "#!$SHELL_PATH"
17       echo shift
18       echo output=1
19       echo "while test -f commandline\$output; do output=\$((\$output+1)); done"
20       echo for a
21       echo do
22       echo "  echo \"!\$a!\""
23       echo "done >commandline\$output"
24       echo "cat > msgtxt\$output"
25       ) >fake.sendmail &&
26      chmod +x ./fake.sendmail &&
27      git add fake.sendmail &&
28      GIT_AUTHOR_NAME="A" git commit -a -m "Second."'
30 clean_fake_sendmail() {
31         rm -f commandline* msgtxt*
32 }
34 test_expect_success 'Extract patches' '
35     patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
36 '
38 # Test no confirm early to ensure remaining tests will not hang
39 test_no_confirm () {
40         rm -f no_confirm_okay
41         echo n | \
42                 GIT_SEND_EMAIL_NOTTY=1 \
43                 git send-email \
44                 --from="Example <from@example.com>" \
45                 --to=nobody@example.com \
46                 --smtp-server="$(pwd)/fake.sendmail" \
47                 $@ \
48                 $patches > stdout &&
49                 test_must_fail grep "Send this email" stdout &&
50                 > no_confirm_okay
51 }
53 # Exit immediately to prevent hang if a no-confirm test fails
54 check_no_confirm () {
55         test -f no_confirm_okay || {
56                 say 'No confirm test failed; skipping remaining tests to prevent hanging'
57                 test_done
58         }
59 }
61 test_expect_success 'No confirm with --suppress-cc' '
62         test_no_confirm --suppress-cc=sob
63 '
64 check_no_confirm
66 test_expect_success 'No confirm with --confirm=never' '
67         test_no_confirm --confirm=never
68 '
69 check_no_confirm
71 # leave sendemail.confirm set to never after this so that none of the
72 # remaining tests prompt unintentionally.
73 test_expect_success 'No confirm with sendemail.confirm=never' '
74         git config sendemail.confirm never &&
75         test_no_confirm --compose --subject=foo
76 '
77 check_no_confirm
79 test_expect_success 'Send patches' '
80      git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
81 '
83 cat >expected <<\EOF
84 !nobody@example.com!
85 !author@example.com!
86 !one@example.com!
87 !two@example.com!
88 EOF
89 test_expect_success \
90     'Verify commandline' \
91     'test_cmp expected commandline1'
93 cat >expected-show-all-headers <<\EOF
94 0001-Second.patch
95 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
96 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
97 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
98 Dry-OK. Log says:
99 Server: relay.example.com
100 MAIL FROM:<from@example.com>
101 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<bcc@example.com>
102 From: Example <from@example.com>
103 To: to@example.com
104 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
105 Subject: [PATCH 1/1] Second.
106 Date: DATE-STRING
107 Message-Id: MESSAGE-ID-STRING
108 X-Mailer: X-MAILER-STRING
109 In-Reply-To: <unique-message-id@example.com>
110 References: <unique-message-id@example.com>
112 Result: OK
113 EOF
115 test_expect_success 'Show all headers' '
116         git send-email \
117                 --dry-run \
118                 --suppress-cc=sob \
119                 --from="Example <from@example.com>" \
120                 --to=to@example.com \
121                 --cc=cc@example.com \
122                 --bcc=bcc@example.com \
123                 --in-reply-to="<unique-message-id@example.com>" \
124                 --smtp-server relay.example.com \
125                 $patches |
126         sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
127                 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
128                 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
129                 >actual-show-all-headers &&
130         test_cmp expected-show-all-headers actual-show-all-headers
133 test_expect_success 'Prompting works' '
134         clean_fake_sendmail &&
135         (echo "Example <from@example.com>"
136          echo "to@example.com"
137          echo ""
138         ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
139                 --smtp-server="$(pwd)/fake.sendmail" \
140                 $patches \
141                 2>errors &&
142                 grep "^From: Example <from@example.com>$" msgtxt1 &&
143                 grep "^To: to@example.com$" msgtxt1
146 z8=zzzzzzzz
147 z64=$z8$z8$z8$z8$z8$z8$z8$z8
148 z512=$z64$z64$z64$z64$z64$z64$z64$z64
149 test_expect_success 'reject long lines' '
150         clean_fake_sendmail &&
151         cp $patches longline.patch &&
152         echo $z512$z512 >>longline.patch &&
153         test_must_fail git send-email \
154                 --from="Example <nobody@example.com>" \
155                 --to=nobody@example.com \
156                 --smtp-server="$(pwd)/fake.sendmail" \
157                 $patches longline.patch \
158                 2>errors &&
159         grep longline.patch errors
162 test_expect_success 'no patch was sent' '
163         ! test -e commandline1
166 test_expect_success 'Author From: in message body' '
167         clean_fake_sendmail &&
168         git send-email \
169                 --from="Example <nobody@example.com>" \
170                 --to=nobody@example.com \
171                 --smtp-server="$(pwd)/fake.sendmail" \
172                 $patches &&
173         sed "1,/^$/d" < msgtxt1 > msgbody1
174         grep "From: A <author@example.com>" msgbody1
177 test_expect_success 'Author From: not in message body' '
178         clean_fake_sendmail &&
179         git send-email \
180                 --from="A <author@example.com>" \
181                 --to=nobody@example.com \
182                 --smtp-server="$(pwd)/fake.sendmail" \
183                 $patches &&
184         sed "1,/^$/d" < msgtxt1 > msgbody1
185         ! grep "From: A <author@example.com>" msgbody1
188 test_expect_success 'allow long lines with --no-validate' '
189         git send-email \
190                 --from="Example <nobody@example.com>" \
191                 --to=nobody@example.com \
192                 --smtp-server="$(pwd)/fake.sendmail" \
193                 --novalidate \
194                 $patches longline.patch \
195                 2>errors
198 test_expect_success 'Invalid In-Reply-To' '
199         clean_fake_sendmail &&
200         git send-email \
201                 --from="Example <nobody@example.com>" \
202                 --to=nobody@example.com \
203                 --in-reply-to=" " \
204                 --smtp-server="$(pwd)/fake.sendmail" \
205                 $patches
206                 2>errors
207         ! grep "^In-Reply-To: < *>" msgtxt1
210 test_expect_success 'Valid In-Reply-To when prompting' '
211         clean_fake_sendmail &&
212         (echo "From Example <from@example.com>"
213          echo "To Example <to@example.com>"
214          echo ""
215         ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
216                 --smtp-server="$(pwd)/fake.sendmail" \
217                 $patches 2>errors &&
218         ! grep "^In-Reply-To: < *>" msgtxt1
221 test_expect_success 'setup fake editor' '
222         (echo "#!$SHELL_PATH" &&
223          echo "echo fake edit >>\"\$1\""
224         ) >fake-editor &&
225         chmod +x fake-editor
228 test_set_editor "$(pwd)/fake-editor"
230 test_expect_success '--compose works' '
231         clean_fake_sendmail &&
232         git send-email \
233         --compose --subject foo \
234         --from="Example <nobody@example.com>" \
235         --to=nobody@example.com \
236         --smtp-server="$(pwd)/fake.sendmail" \
237         $patches \
238         2>errors
241 test_expect_success 'first message is compose text' '
242         grep "^fake edit" msgtxt1
245 test_expect_success 'second message is patch' '
246         grep "Subject:.*Second" msgtxt2
249 cat >expected-suppress-sob <<\EOF
250 0001-Second.patch
251 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
252 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
253 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
254 Dry-OK. Log says:
255 Server: relay.example.com
256 MAIL FROM:<from@example.com>
257 RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
258 From: Example <from@example.com>
259 To: to@example.com
260 Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
261 Subject: [PATCH 1/1] Second.
262 Date: DATE-STRING
263 Message-Id: MESSAGE-ID-STRING
264 X-Mailer: X-MAILER-STRING
266 Result: OK
267 EOF
269 test_suppression () {
270         git send-email \
271                 --dry-run \
272                 --suppress-cc=$1 \
273                 --from="Example <from@example.com>" \
274                 --to=to@example.com \
275                 --smtp-server relay.example.com \
276                 $patches |
277         sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
278                 -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
279                 -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
280                 >actual-suppress-$1 &&
281         test_cmp expected-suppress-$1 actual-suppress-$1
284 test_expect_success 'sendemail.cc set' '
285         git config sendemail.cc cc@example.com &&
286         test_suppression sob
289 cat >expected-suppress-sob <<\EOF
290 0001-Second.patch
291 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
292 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
293 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
294 Dry-OK. Log says:
295 Server: relay.example.com
296 MAIL FROM:<from@example.com>
297 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
298 From: Example <from@example.com>
299 To: to@example.com
300 Cc: A <author@example.com>, One <one@example.com>, two@example.com
301 Subject: [PATCH 1/1] Second.
302 Date: DATE-STRING
303 Message-Id: MESSAGE-ID-STRING
304 X-Mailer: X-MAILER-STRING
306 Result: OK
307 EOF
309 test_expect_success 'sendemail.cc unset' '
310         git config --unset sendemail.cc &&
311         test_suppression sob
314 cat >expected-suppress-all <<\EOF
315 0001-Second.patch
316 Dry-OK. Log says:
317 Server: relay.example.com
318 MAIL FROM:<from@example.com>
319 RCPT TO:<to@example.com>
320 From: Example <from@example.com>
321 To: to@example.com
322 Subject: [PATCH 1/1] Second.
323 Date: DATE-STRING
324 Message-Id: MESSAGE-ID-STRING
325 X-Mailer: X-MAILER-STRING
327 Result: OK
328 EOF
330 test_expect_success '--suppress-cc=all' '
331         test_suppression all
334 cat >expected-suppress-body <<\EOF
335 0001-Second.patch
336 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
337 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
338 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
339 Dry-OK. Log says:
340 Server: relay.example.com
341 MAIL FROM:<from@example.com>
342 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
343 From: Example <from@example.com>
344 To: to@example.com
345 Cc: A <author@example.com>, One <one@example.com>, two@example.com
346 Subject: [PATCH 1/1] Second.
347 Date: DATE-STRING
348 Message-Id: MESSAGE-ID-STRING
349 X-Mailer: X-MAILER-STRING
351 Result: OK
352 EOF
354 test_expect_success '--suppress-cc=body' '
355         test_suppression body
358 cat >expected-suppress-sob <<\EOF
359 0001-Second.patch
360 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
361 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
362 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
363 Dry-OK. Log says:
364 Server: relay.example.com
365 MAIL FROM:<from@example.com>
366 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
367 From: Example <from@example.com>
368 To: to@example.com
369 Cc: A <author@example.com>, One <one@example.com>, two@example.com
370 Subject: [PATCH 1/1] Second.
371 Date: DATE-STRING
372 Message-Id: MESSAGE-ID-STRING
373 X-Mailer: X-MAILER-STRING
375 Result: OK
376 EOF
378 test_expect_success '--suppress-cc=sob' '
379         test_suppression sob
382 cat >expected-suppress-bodycc <<\EOF
383 0001-Second.patch
384 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
385 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
386 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
387 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
388 Dry-OK. Log says:
389 Server: relay.example.com
390 MAIL FROM:<from@example.com>
391 RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
392 From: Example <from@example.com>
393 To: to@example.com
394 Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
395 Subject: [PATCH 1/1] Second.
396 Date: DATE-STRING
397 Message-Id: MESSAGE-ID-STRING
398 X-Mailer: X-MAILER-STRING
400 Result: OK
401 EOF
403 test_expect_success '--suppress-cc=bodycc' '
404         test_suppression bodycc
407 cat >expected-suppress-cc <<\EOF
408 0001-Second.patch
409 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
410 (body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
411 Dry-OK. Log says:
412 Server: relay.example.com
413 MAIL FROM:<from@example.com>
414 RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
415 From: Example <from@example.com>
416 To: to@example.com
417 Cc: A <author@example.com>, C O Mitter <committer@example.com>
418 Subject: [PATCH 1/1] Second.
419 Date: DATE-STRING
420 Message-Id: MESSAGE-ID-STRING
421 X-Mailer: X-MAILER-STRING
423 Result: OK
424 EOF
426 test_expect_success '--suppress-cc=cc' '
427         test_suppression cc
430 test_confirm () {
431         echo y | \
432                 GIT_SEND_EMAIL_NOTTY=1 \
433                 git send-email \
434                 --from="Example <nobody@example.com>" \
435                 --to=nobody@example.com \
436                 --smtp-server="$(pwd)/fake.sendmail" \
437                 $@ $patches > stdout &&
438         grep "Send this email" stdout
441 test_expect_success '--confirm=always' '
442         test_confirm --confirm=always --suppress-cc=all
445 test_expect_success '--confirm=auto' '
446         test_confirm --confirm=auto
449 test_expect_success '--confirm=cc' '
450         test_confirm --confirm=cc
453 test_expect_success '--confirm=compose' '
454         test_confirm --confirm=compose --compose
457 test_expect_success 'confirm by default (due to cc)' '
458         CONFIRM=$(git config --get sendemail.confirm) &&
459         git config --unset sendemail.confirm &&
460         test_confirm
461         ret="$?"
462         git config sendemail.confirm ${CONFIRM:-never}
463         test $ret = "0"
466 test_expect_success 'confirm by default (due to --compose)' '
467         CONFIRM=$(git config --get sendemail.confirm) &&
468         git config --unset sendemail.confirm &&
469         test_confirm --suppress-cc=all --compose
470         ret="$?"
471         git config sendemail.confirm ${CONFIRM:-never}
472         test $ret = "0"
475 test_expect_success 'confirm detects EOF (inform assumes y)' '
476         CONFIRM=$(git config --get sendemail.confirm) &&
477         git config --unset sendemail.confirm &&
478         rm -fr outdir &&
479         git format-patch -2 -o outdir &&
480         GIT_SEND_EMAIL_NOTTY=1 \
481                 git send-email \
482                         --from="Example <nobody@example.com>" \
483                         --to=nobody@example.com \
484                         --smtp-server="$(pwd)/fake.sendmail" \
485                         outdir/*.patch < /dev/null
486         ret="$?"
487         git config sendemail.confirm ${CONFIRM:-never}
488         test $ret = "0"
491 test_expect_success 'confirm detects EOF (auto causes failure)' '
492         CONFIRM=$(git config --get sendemail.confirm) &&
493         git config sendemail.confirm auto &&
494         GIT_SEND_EMAIL_NOTTY=1 &&
495         export GIT_SEND_EMAIL_NOTTY &&
496                 test_must_fail git send-email \
497                         --from="Example <nobody@example.com>" \
498                         --to=nobody@example.com \
499                         --smtp-server="$(pwd)/fake.sendmail" \
500                         $patches < /dev/null
501         ret="$?"
502         git config sendemail.confirm ${CONFIRM:-never}
503         test $ret = "0"
506 test_expect_success 'confirm doesnt loop forever' '
507         CONFIRM=$(git config --get sendemail.confirm) &&
508         git config sendemail.confirm auto &&
509         GIT_SEND_EMAIL_NOTTY=1 &&
510         export GIT_SEND_EMAIL_NOTTY &&
511                 yes "bogus" | test_must_fail git send-email \
512                         --from="Example <nobody@example.com>" \
513                         --to=nobody@example.com \
514                         --smtp-server="$(pwd)/fake.sendmail" \
515                         $patches
516         ret="$?"
517         git config sendemail.confirm ${CONFIRM:-never}
518         test $ret = "0"
521 test_expect_success 'utf8 Cc is rfc2047 encoded' '
522         clean_fake_sendmail &&
523         rm -fr outdir &&
524         git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
525         git send-email \
526         --from="Example <nobody@example.com>" \
527         --to=nobody@example.com \
528         --smtp-server="$(pwd)/fake.sendmail" \
529         outdir/*.patch &&
530         grep "^Cc:" msgtxt1 |
531         grep "=?utf-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
534 test_expect_success '--compose adds MIME for utf8 body' '
535         clean_fake_sendmail &&
536         (echo "#!$SHELL_PATH" &&
537          echo "echo utf8 body: àéìöú >>\"\$1\""
538         ) >fake-editor-utf8 &&
539         chmod +x fake-editor-utf8 &&
540           GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
541           git send-email \
542           --compose --subject foo \
543           --from="Example <nobody@example.com>" \
544           --to=nobody@example.com \
545           --smtp-server="$(pwd)/fake.sendmail" \
546           $patches &&
547         grep "^utf8 body" msgtxt1 &&
548         grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
551 test_expect_success '--compose respects user mime type' '
552         clean_fake_sendmail &&
553         (echo "#!$SHELL_PATH" &&
554          echo "(echo MIME-Version: 1.0"
555          echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
556          echo " echo Content-Transfer-Encoding: 8bit"
557          echo " echo Subject: foo"
558          echo " echo "
559          echo " echo utf8 body: àéìöú) >\"\$1\""
560         ) >fake-editor-utf8-mime &&
561         chmod +x fake-editor-utf8-mime &&
562           GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
563           git send-email \
564           --compose --subject foo \
565           --from="Example <nobody@example.com>" \
566           --to=nobody@example.com \
567           --smtp-server="$(pwd)/fake.sendmail" \
568           $patches &&
569         grep "^utf8 body" msgtxt1 &&
570         grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
571         ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
574 test_expect_success '--compose adds MIME for utf8 subject' '
575         clean_fake_sendmail &&
576           GIT_EDITOR="\"$(pwd)/fake-editor\"" \
577           git send-email \
578           --compose --subject utf8-sübjëct \
579           --from="Example <nobody@example.com>" \
580           --to=nobody@example.com \
581           --smtp-server="$(pwd)/fake.sendmail" \
582           $patches &&
583         grep "^fake edit" msgtxt1 &&
584         grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
587 test_expect_success 'detects ambiguous reference/file conflict' '
588         echo master > master &&
589         git add master &&
590         git commit -m"add master" &&
591         test_must_fail git send-email --dry-run master 2>errors &&
592         grep disambiguate errors
595 test_expect_success 'feed two files' '
596         rm -fr outdir &&
597         git format-patch -2 -o outdir &&
598         git send-email \
599         --dry-run \
600         --from="Example <nobody@example.com>" \
601         --to=nobody@example.com \
602         outdir/000?-*.patch 2>errors >out &&
603         grep "^Subject: " out >subjects &&
604         test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
605         test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
608 test_expect_success 'in-reply-to but no threading' '
609         git send-email \
610                 --dry-run \
611                 --from="Example <nobody@example.com>" \
612                 --to=nobody@example.com \
613                 --in-reply-to="<in-reply-id@example.com>" \
614                 --no-thread \
615                 $patches |
616         grep "In-Reply-To: <in-reply-id@example.com>"
619 test_done