setup:
  - do:
      indices.create:
        index: airline-data
        body:
          mappings:
            properties:
              time:
                type: date
              airline:
                type: keyword
              responsetime:
                type: float
              event_rate:
                type: integer

---
"Test get all transforms when there are none":
  - do:
      transform.get_transform:
        transform_id: "*"
  - match: { count: 0 }
  - match: { transforms: [] }

  - do:
      catch: missing
      transform.get_transform:
        transform_id: "*"
        allow_no_match: false

---
"Test get transform when it does not exist":
  - do:
      catch: /Transform with id \[missing-transform-id\] could not be found/
      transform.get_transform:
        transform_id: "missing-transform-id"

---
"Test delete transform when it does not exist":
  - do:
      catch: missing
      transform.delete_transform:
        transform_id: "missing transform"

---
"Test put transform with frequency too low":
  - do:
      catch: /minimum permitted \[frequency\] is \[1s\]/
      transform.put_transform:
        transform_id: "frequency-too-low"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest" },
            "frequency": "999ms",
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

---
"Test put transform with frequency too high":
  - do:
      catch: /highest permitted \[frequency\] is \[1h\]/
      transform.put_transform:
        transform_id: "frequency-too-low"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest" },
            "frequency": "3600001ms",
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

---
"Test put transform with invalid source index":
  - do:
      catch: /.*Validation Failed.* no such index \[missing-index\]/
      transform.put_transform:
        transform_id: "missing-source-transform"
        body: >
          {
            "source": { "index": "missing-index" },
            "dest": { "index": "missing-source-dest" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      transform.put_transform:
        transform_id: "missing-source-transform"
        defer_validation: true
        body: >
          {
            "source": { "index": "missing-index" },
            "dest": { "index": "missing-source-dest" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }

---
"Test put transform with invalid source index pattern":
  - do:
      # The transform can be created even though the source index pattern resolves to empty set of concrete indices.
      transform.put_transform:
        transform_id: "missing-source-transform-pattern"
        body: >
          {
            "source": { "index": "missing-index*" },
            "dest": { "index": "missing-source-dest" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }

  - do:
      # The transform can be updated even though the source index pattern resolves to empty set of concrete indices.
      transform.update_transform:
        transform_id: "missing-source-transform-pattern"
        body: >
          {
            "description": "updated description"
          }
  - match: { id: "missing-source-transform-pattern" }
  - match: { description: "updated description" }

  - do:
      # The transform can be started even though the source index pattern resolves to empty set of concrete indices.
      transform.start_transform:
        transform_id: "missing-source-transform-pattern"
  - match: { acknowledged: true }

---
"Test basic transform crud":
  - do:
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data"
          }
  - match: { acknowledged: true }

  - do:
      ingest.put_pipeline:
        id: "airline-pipeline"
        body:  >
          {
            "processors": [
              {
                "set" : {
                  "field" : "some_field",
                  "value" : 42
                }
              }
            ]
          }
  - match: { acknowledged: true }

  - do:
      transform.put_transform:
        transform_id: "airline-transform-dos"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline-again", "pipeline": "airline-pipeline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }

  - do:
      transform.get_transform:
        transform_id: "airline-transform"
  - match: { count: 1 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.0.source.index.0: "airline-data" }
  - match: { transforms.0.dest.index: "airline-data-by-airline" }
  - is_true: transforms.0.source.query.match_all
  - is_true: transforms.0.create_time
  - is_true: transforms.0.version
  - match: { transforms.0.pivot.group_by.airline.terms.field: "airline" }
  - match: { transforms.0.pivot.aggregations.avg_response.avg.field: "responsetime" }
  - match: { transforms.0.description: "yaml test transform on airline-data" }
  - is_true: transforms.0.authorization.roles

  - do:
      transform.get_transform:
        transform_id: "*"
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.1.id: "airline-transform-dos" }
  - is_false: transforms.1.description

  - do:
      transform.get_transform:
        transform_id: "_all"
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.1.id: "airline-transform-dos" }
  - do:
      transform.get_transform:
        transform_id: "airline-transform,airline-transform-dos"
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.1.id: "airline-transform-dos" }
  - is_true: transforms.0.authorization.roles
  - is_true: transforms.1.authorization.roles

  - do:
      transform.get_transform:
        transform_id: "airline-transform*"
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.1.id: "airline-transform-dos" }

  - do:
      transform.get_transform:
        transform_id: "airline-transform*"
        from: 0
        size: 1
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform" }

  - do:
      transform.get_transform:
        transform_id: "airline-transform*"
        from: 1
        size: 1
  - match: { count: 2 }
  - match: { transforms.0.id: "airline-transform-dos" }

---
"Test transform with query and array of indices in source":
  - do:
      indices.create:
        index: airline-data-other
        body:
          mappings:
            properties:
              time:
                type: date
              airline:
                type: keyword
              responsetime:
                type: float
              event_rate:
                type: integer

  - do:
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": ["airline-data", "airline-data-other"],
              "query": {"bool":{"filter":{"term":{"airline":"FOO"}}}}
            },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }
  - do:
      transform.get_transform:
        transform_id: "airline-transform"
  - match: { count: 1 }
  - match: { transforms.0.id: "airline-transform" }
  - match: { transforms.0.source.index.0: "airline-data" }
  - match: { transforms.0.source.index.1: "airline-data-other" }
  - match: { transforms.0.source.query.bool.filter.term.airline: "FOO" }
  - match: { transforms.0.dest.index: "airline-data-by-airline" }
  - match: { transforms.0.pivot.group_by.airline.terms.field: "airline" }
  - match: { transforms.0.pivot.aggregations.avg_response.avg.field: "responsetime" }

---
"Test PUT continuous transform":
  - do:
      transform.put_transform:
        transform_id: "airline-transform-continuous"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "airline-data-by-airline-continuous" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "sync": {
              "time": {
                "field": "time",
                "delay": "90m"
              }
            }
          }
  - match: { acknowledged: true }
  - do:
      transform.get_transform:
        transform_id: "airline-transform-continuous"
  - match: { count: 1 }
  - match: { transforms.0.id: "airline-transform-continuous" }
  - match: { transforms.0.source.index.0: "airline-data" }
  - match: { transforms.0.dest.index: "airline-data-by-airline-continuous" }
  - match: { transforms.0.pivot.group_by.airline.terms.field: "airline" }
  - match: { transforms.0.pivot.aggregations.avg_response.avg.field: "responsetime" }
  - match: { transforms.0.sync.time.field: "time" }
  - match: { transforms.0.sync.time.delay: "90m" }
  - is_true: transforms.0.authorization.roles

---
"Test PUT continuous transform without delay set":
  - do:
      transform.put_transform:
        transform_id: "airline-transform-continuous"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "airline-data-by-airline-continuous" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "sync": {
              "time": {
                "field": "time"
              }
            }
          }
  - match: { acknowledged: true }
  - do:
      transform.get_transform:
        transform_id: "airline-transform-continuous"
  - match: { count: 1 }
  - match: { transforms.0.id: "airline-transform-continuous" }
  - match: { transforms.0.source.index.0: "airline-data" }
  - match: { transforms.0.dest.index: "airline-data-by-airline-continuous" }
  - match: { transforms.0.pivot.group_by.airline.terms.field: "airline" }
  - match: { transforms.0.pivot.aggregations.avg_response.avg.field: "responsetime" }
  - match: { transforms.0.sync.time.field: "time" }
  - match: { transforms.0.sync.time.delay: "60s" }
---
"Test transform with invalid page parameter":
  - do:
      catch: /Param \[size\] has a max acceptable value of \[1000\]/
      transform.get_transform:
        transform_id: "_all"
        from: 0
        size: 10000
---
"Test transform where dest is included in source":
  - do:
      catch: /Destination index \[airline-data-by-airline\] is included in source expression \[airline-data/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": ["airline-data*"]
            },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

  - do:
      transform.put_transform:
        transform_id: "airline-transform"
        defer_validation: true
        body: >
          {
            "source": {
              "index": ["airline-data*"]
            },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

---
"Test transform where source query is invalid":
  - do:
      catch: /The mapper type \[bad-type\] declared on runtime field \[rt-field\]/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": ["airline-data*"],
              "runtime_mappings": {"rt-field":{"type": "bad-type"}}
            },
            "dest": { "index": "dest-airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      transform.put_transform:
        transform_id: "airline-transform"
        defer_validation: true
        body: >
          {
            "source": {
              "index": ["airline-data*"],
              "runtime_mappings": {"rt-field":{"type": "bad-type"}}
            },
            "dest": { "index": "dest-airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }

---
"Test alias scenarios":
  - do:
      indices.create:
        index: created-destination-index
  - do:
      indices.create:
        index: second-created-destination-index
  - do:
      indices.put_alias:
        index: airline-data
        name: source-index
  - do:
      indices.put_alias:
        index: created-destination-index
        name: dest-index
  - do:
      transform.put_transform:
        transform_id: "transform-from-aliases"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - match: { acknowledged: true }

  - do:
      indices.put_alias:
        index: created-destination-index
        name: source-index

  - do:
      catch: /.*Validation Failed.* Destination index \[created-destination-index\] is included in source expression \[airline-data,created-destination-index\]/
      transform.put_transform:
        transform_id: "transform-from-aliases-failures"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

  - do:
      indices.delete_alias:
        index: created-destination-index
        name: source-index

  - do:
      indices.put_alias:
        index: second-created-destination-index
        name: dest-index

  - do:
      catch: /.*Validation Failed.* no write index is defined for alias [dest2-index].*/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": ["source-index"]
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
---
"Test put config with invalid pivot size":
  - do:
      catch: /pivot\.max_page_search_size \[5\] is out of range. The minimum value is 10 and the maximum is 65536/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest-index" },
            "pivot": {
              "max_page_search_size": 5,
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      catch: /pivot\.max_page_search_size \[75000\] is out of range. The minimum value is 10 and the maximum is 65536/

      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest-index" },
            "pivot": {
              "max_page_search_size": 75000,
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

---
"Test put config with invalid number of failure retries":
  - do:
      catch: /settings\.num_failure_retries \[-2\] is out of range. The minimum value is -1 \(infinity\) and the maximum is 100/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "settings": {
              "num_failure_retries": -2
            }
          }
  - do:
      catch: /settings\.num_failure_retries \[101\] is out of range. The minimum value is -1 \(infinity\) and the maximum is 100/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "settings": {
              "num_failure_retries": 101
            }
          }

---
"Test creation failures due to duplicate and conflicting field names":
  - do:
      catch: /duplicate field \[airline\] detected/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"airline": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      catch: /field \[airline\] cannot be both an object and a field/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"airline.responsetime": {"avg": {"field": "responsetime"}}}
            }
          }
---
"Test invalid transform id":
  - do:
      catch: /can contain lowercase alphanumeric \(a-z and 0-9\), hyphens or underscores; must start and end with alphanumeric/
      transform.put_transform:
        transform_id: "!@#$%^&*(duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline.id": {"terms": {"field": "airline"}}},
              "aggs": {"airline.response": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      catch: /The id cannot contain more than 64 character/
      transform.put_transform:
        transform_id: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        body: >
          {
            "source": {
              "index": "source-index"
            },
            "dest": { "index": "dest-index" },
            "pivot": {
              "group_by": { "airline.id": {"terms": {"field": "airline"}}},
              "aggs": {"airline.response": {"avg": {"field": "responsetime"}}}
            }
          }
---
"Test invalid destination index name":
  - do:
      catch: /.*Validation Failed.* Destination index \[DeStInAtIoN\] must be lowercase/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "DeStInAtIoN" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }
  - do:
      catch: /Invalid index name \[destination#dest\], must not contain \'#\'/
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "destination#dest" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            }
          }

---
"Test put valid config with create_time in the body":

  - do:
      catch: /Found \[create_time\], not allowed for strict parsing/
      transform.put_transform:
        transform_id: "airline-transform-with-create-time"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data",
            "create_time": 123456789
          }

---
"Test put valid config with version in the body":

  - do:
      catch: /Found \[version\], not allowed for strict parsing/
      transform.put_transform:
        transform_id: "airline-transform-with-version"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data",
            "version": "7.3.0"
          }
---
"Test put transform with missing pipeline":
  - do:
      catch: /Pipeline with id \[missing-transform-pipeline\] could not be found/
      transform.put_transform:
        transform_id: "airline-transform-with-missing-pipeline-crud"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline-with-pipeline", "pipeline": "missing-transform-pipeline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data"
          }
---
"Test put transform with missing pipeline and defer validations":
  - do:
      transform.put_transform:
        defer_validation: true
        transform_id: "airline-transform-with-missing-pipeline-crud-defer"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline", "pipeline": "missing-transform-pipeline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data"
          }
  - match: {acknowledged: true}
---
"Test put transform with bad query due to script compilation":
  - do:
      catch: bad_request
      transform.put_transform:
        transform_id: "airline-transform-with-bad-scripts"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline-with-bad-scripts" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {
                "sumState": {
                  "scripted_metric": {
                    "combine_script": {
                      "source": "foobar boom"
                    },
                    "init_script": {
                      "source": "state.state = []"
                    },
                    "map_script": {
                      "source": "state.state.add(1)"
                    },
                    "reduce_script": {
                      "source": "long sum = 0; for (s in states) { sum += s } return sum"
                    }
                  }
                }
              }
            },
            "description": "yaml test transform on airline-data"
          }

---
"Test transform for export":
  - do:
      transform.put_transform:
        transform_id: "airline-transform"
        body: >
          {
            "source": { "index": "airline-data" },
            "dest": { "index": "airline-data-by-airline" },
            "pivot": {
              "group_by": { "airline": {"terms": {"field": "airline"}}},
              "aggs": {"avg_response": {"avg": {"field": "responsetime"}}}
            },
            "description": "yaml test transform on airline-data"
          }
  - match: { acknowledged: true }

  - do:
      transform.get_transform:
        transform_id: "airline-transform"
        exclude_generated: true

  - match: {transforms.0.source.index: ["airline-data"]}
  - match: {transforms.0.dest.index: "airline-data-by-airline"}
  - match: {transforms.0.pivot.group_by.airline.terms.field: "airline"}
  - match: {transforms.0.pivot.aggregations.avg_response.avg.field: "responsetime"}
  - match: {transforms.0.description: "yaml test transform on airline-data"}
  - match: {transforms.0.id: "airline-transform"}
  - is_false: transforms.0.create_time
  - is_false: transforms.0.version

---
"Test creation failures of latest function":
  - do:
      catch: /latest.unique_key must be non-empty/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "dest-index" },
            "latest": {
              "unique_key": [],
              "sort": "time"
            }
          }

  - do:
      catch: /latest.unique_key\[1\] element must be non-empty/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "dest-index" },
            "latest": {
              "unique_key": [ "airline", "" ],
              "sort": "time"
            }
          }

  - do:
      catch: /latest.unique_key elements must be unique, found duplicate element \[airline\]/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "dest-index" },
            "latest": {
              "unique_key": [ "airline", "airline" ],
              "sort": "time"
            }
          }

  - do:
      catch: /latest.sort must be non-empty/
      transform.put_transform:
        transform_id: "duplicate-field-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "dest-index" },
            "latest": {
              "unique_key": [ "airline" ],
              "sort": ""
            }
          }

---
"Test creation of latest function":
  - do:
      transform.put_transform:
        transform_id: "latest-by-airline-transform"
        body: >
          {
            "source": {
              "index": "airline-data"
            },
            "dest": { "index": "latest-by-airline" },
            "latest": {
              "unique_key": [ "airline" ],
              "sort": "time"
            },
            "description": "yaml test latest transform on airline-data"
          }
  - match: { acknowledged: true }

  - do:
      transform.get_transform:
        transform_id: "latest-by-airline-transform"
  - match: { count: 1 }
  - match: { transforms.0.id: "latest-by-airline-transform" }
  - match: { transforms.0.source.index.0: "airline-data" }
  - match: { transforms.0.dest.index: "latest-by-airline" }
  - is_true: transforms.0.source.query.match_all
  - is_true: transforms.0.create_time
  - is_true: transforms.0.version
  - match: { transforms.0.latest.unique_key.0: "airline" }
  - match: { transforms.0.latest.sort: "time" }
  - match: { transforms.0.description: "yaml test latest transform on airline-data" }
