1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! Module containing code to deal with verifying interactions via plugins

use std::collections::HashMap;

use bytes::Bytes;
use itertools::Either;
use pact_models::prelude::OptionalBody;
use serde_json::Value;

use crate::proto::{VerificationResult, verification_result_item};

/// Data required to execute the verification of an interaction
#[derive(Clone, Debug, Default)]
pub struct InteractionVerificationData {
  /// Data for the request of the interaction
  pub request_data: OptionalBody,
  /// Metadata associated with the request
  pub metadata: HashMap<String, Either<Value, Bytes>>
}

impl InteractionVerificationData {
  /// Create a new InteractionVerificationData struct
  pub fn new(request_data: OptionalBody, metadata: HashMap<String, Either<Value, Bytes>>) -> Self {
    InteractionVerificationData {
      request_data,
      metadata,
    }
  }
}

/// Result of running an integration verification
#[derive(Clone, Debug, Default)]
pub struct InteractionVerificationResult {
  /// If the verification was successful
  pub ok: bool,
  /// List of errors if not successful
  pub details: Vec<InteractionVerificationDetails>,
  /// Output to display to the user
  pub output: Vec<String>
}

/// Details on an individual failure
#[derive(Clone, Debug)]
pub enum InteractionVerificationDetails {
  /// Error occurred
  Error(String),

  /// Mismatch occurred
  Mismatch {
    expected: Bytes,
    actual: Bytes,
    mismatch: String,
    path: String
  }
}

impl From<&VerificationResult> for InteractionVerificationResult {
  fn from(result: &VerificationResult) -> Self {
    InteractionVerificationResult {
      ok: result.success,
      details: result.mismatches.iter()
        .filter_map(|r| r.result.as_ref().map(|r| match r {
          verification_result_item::Result::Error(err) => InteractionVerificationDetails::Error(err.to_string()),
          verification_result_item::Result::Mismatch(mismatch) => InteractionVerificationDetails::Mismatch {
            expected: mismatch.expected.clone().map(|b| Bytes::from(b)).unwrap_or_default(),
            actual: mismatch.actual.clone().map(|b| Bytes::from(b)).unwrap_or_default(),
            mismatch: mismatch.mismatch.to_string(),
            path: mismatch.path.to_string()
          }
        }))
        .collect(),
      output: result.output.clone()
    }
  }
}