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