hunk.code_window:             'subject': 'sendgrid-send-email unit test'}
           self.personalization_custom_args = {'arg1': 'val1', 'arg2': 'val2'}
           self.categories = ['cat1', 'cat2']
           self.expected_mail_data_extras = copy.deepcopy(self.expected_mail_data)
           self.expected_mail_data_extras['personalizations'][0]['custom_args'] = \
               self.personalization_custom_args
           self.expected_mail_data_extras['categories'] = self.categories
  
hunk.labels: keep keep add keep keep keep keep
hunk.after_edit:         # extras
  
hunk.file_path: tests/contrib/utils/test_sendgrid.py
hunk.type: add
file: /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License. You may obtain a copy of the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
  
  body { padding-top: 70px; }
  .container {
      width: 100%;
  }
  a.navbar-brand span {
      color: white;
  }
  .modal-backdrop{
      z-index: 0;
      position: fixed;
  }
  .modal-content{
      z-index: 5;
  }
  nav{
      -webkit-box-shadow: 0px 3px 3px #AAA;
      -moz-box-shadow:    0px 3px 3px #AAA;
      box-shadow:         0px 3px 3px #AAA;
      z-index:999;
  }
  a.navbar-brand {
      cursor: default;
  }
  td>span.glyphicon{
      padding-left: 3px;
      padding-top: 3px;
  }
  button.btn {
      border: 1px solid black;
  }
  
  div.rich_doc {
      padding: 5px 10px;
      border: 1px solid #dddddd;
      background: white;
      border-radius: 4px;
  }
  
  span.status_square {
      width:10px;
      height:10px;
      border:1px solid grey;
      display:inline-block;
      padding-left: 0px;
      cursor: pointer;
  }
  div.squares{
      float:right;
      font-size: 1;
  }
  div.task_row{
  }
  span.success{
      background-color: green;
  }
  span.up_for_retry{
      background-color: gold;
  }
  span.started{
      background-color: lime;
  }
  span.error{
      background-color: red;
  }
  span.queued{
      background-color: gray;
  }
  span.upstream_failed{
      background-color: orange;
  }
  span.skipped{
      background-color: pink;
  }
  .tooltip-inner {
      max-width: 500px;
      text-align:left !important;
      font-size: 12px;
  }
  input#execution_date {
      margin-bottom: 0px;
  }
  table.highlighttable{
      width: 100%;
      table-layout:fixed;
  }
  div.linenodiv {
      padding-right: 1px !important;
  }
  .linenos {
      width: 50px;
      border: none;
  }
  div.linenodiv  pre {
      padding-left: 4px;
      padding-right: 4px;
      color: #AAA;
      background-color: #FCFCFC;
      text-align:right;
  }
  
  pre {
    overflow: auto;
    word-wrap: normal;
    white-space: pre;
  }
  pre code {
      overflow-wrap: normal;
      white-space: pre;
  }
  input, select {
      margin: 0px;
  }
  .code {
      font-family: monospace;
  }
  
  #sql {
      border: 1px solid #CCC;
      border-radius: 5px;
  }
  .ace_editor div {
      font: inherit!important
  }
  #ace_container {
      margin: 10px 0px;
  }
  #sql_ace {
      visibility: hidden;
  }
  table.dataframe {
      font-size: 12px;
  }
  table.dataframe tbody tr td {
      padding: 2px;
  }
  table thead th {
      background-color: #F3F3F3;
  }
  table.dataframe.dataTable thead > tr > th {
      padding: 10px 20px 10px 10px;
  }
  table.dataTable.dataframe thead .sorting {
      background: url('sort_both.png') no-repeat center right
  }
  table.dataTable.dataframe thead .sorting_desc {
      background: url('sort_desc.png') no-repeat center right
  }
  table.dataTable.dataframe thead .sorting_asc {
      background: url('sort_asc.png') no-repeat center right
  }
  .no-wrap {
      white-space: nowrap;
  }
  div.form-inline{
      margin-bottom: 5px;
  }
  
  body div.panel {
      padding: 0px;
  }
  .blur {
      filter:url(#blur-effect-1);
  }
  div.legend_item {
      -moz-border-radius: 5px/5px;
      -webkit-border-radius: 5px 5px;
      border-radius: 5px/5px;
      float:right;
      margin: 0px 3px 0px 0px;
      padding:0px 3px;
      border:solid 2px grey;
      font-size: 11px;
  }
  div.legend_circle{
      -moz-border-radius: 10px/10px;
      -webkit-border-radius: 10px 10px;
      border-radius: 10px/10px;
      width:15px;
      height:15px;
      border:1px solid grey;
      float:left;
      margin-top: 2px;
      margin-right: 0px;
  }
  div.square {
      width:12px;
      height:12px;
      float: right;
      margin-top: 2px;
      border:1px solid black;
  }
  .btn:active, .btn.active {
    box-shadow: inset 0 6px 6px rgba(0, 0, 0, 0.4);
  }
  
  .hll { background-color: #ffffcc }
  .c { color: #408080; font-style: italic } /* Comment */
  .err { border: 1px solid #FF0000 } /* Error */
  .k { color: #008000; font-weight: bold } /* Keyword */
  .o { color: #666666 } /* Operator */
  .cm { color: #408080; font-style: italic } /* Comment.Multiline */
  .cp { color: #BC7A00 } /* Comment.Preproc */
  .c1 { color: #408080; font-style: italic } /* Comment.Single */
  .cs { color: #408080; font-style: italic } /* Comment.Special */
  .gd { color: #A00000 } /* Generic.Deleted */
  .ge { font-style: italic } /* Generic.Emph */
  .gr { color: #FF0000 } /* Generic.Error */
  .gh { color: #000080; font-weight: bold } /* Generic.Heading */
  .gi { color: #00A000 } /* Generic.Inserted */
  .go { color: #888888 } /* Generic.Output */
  .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
  .gs { font-weight: bold } /* Generic.Strong */
  .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
  .gt { color: #0044DD } /* Generic.Traceback */
  .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
  .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
  .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
  .kp { color: #008000 } /* Keyword.Pseudo */
  .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
  .kt { color: #B00040 } /* Keyword.Type */
  .m { color: #666666 } /* Literal.Number */
  .s { color: #BA2121 } /* Literal.String */
  .na { color: #7D9029 } /* Name.Attribute */
  .nb { color: #008000 } /* Name.Builtin */
  .nc { color: #0000FF; font-weight: bold } /* Name.Class */
  .no { color: #880000 } /* Name.Constant */
  .nd { color: #AA22FF } /* Name.Decorator */
  .ni { color: #999999; font-weight: bold } /* Name.Entity */
  .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
  .nf { color: #0000FF } /* Name.Function */
  .nl { color: #A0A000 } /* Name.Label */
  .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
  .nt { color: #008000; font-weight: bold } /* Name.Tag */
  .nv { color: #19177C } /* Name.Variable */
  .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
  .w { color: #bbbbbb } /* Text.Whitespace */
  .mb { color: #666666 } /* Literal.Number.Bin */
  .mf { color: #666666 } /* Literal.Number.Float */
  .mh { color: #666666 } /* Literal.Number.Hex */
  .mi { color: #666666 } /* Literal.Number.Integer */
  .mo { color: #666666 } /* Literal.Number.Oct */
  .sb { color: #BA2121 } /* Literal.String.Backtick */
  .sc { color: #BA2121 } /* Literal.String.Char */
  .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
  .s2 { color: #BA2121 } /* Literal.String.Double */
  