use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum TestSpec {
AllOf(Vec<TestSpec>),
OneOf(Vec<TestSpec>),
Data(DataSpec),
Crud(CrudSpec),
Search(SearchSpec),
Operation(OperationSpec),
Negative(NegativeSpec),
EdgeCase(EdgeCaseSpec),
Conformance(ConformanceSpec),
Security(SecuritySpec),
Performance(PerformanceSpec),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataSpec {
#[serde(default = "default_data_count")]
pub count: u64,
#[serde(default)]
pub variations: Vec<DataVariation>,
}
impl Default for DataSpec {
fn default() -> Self {
Self {
count: 3,
variations: vec![
DataVariation::HappyPath,
DataVariation::Minimal,
DataVariation::ToBeDeleted,
],
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum DataVariation {
HappyPath,
Minimal,
DuplicateValue {
field: String,
},
MissingField {
field: String,
},
SpecialChars,
Boundary {
field: String,
},
ToBeDeleted,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrudSpec {
#[serde(default = "default_true")]
pub create: bool,
#[serde(default = "default_true")]
pub read: bool,
#[serde(default)]
pub vread: bool,
#[serde(default = "default_true")]
pub update: bool,
#[serde(default = "default_true")]
pub delete: bool,
#[serde(default)]
pub patch: bool,
#[serde(default)]
pub history_instance: bool,
#[serde(default)]
pub history_type: bool,
#[serde(default)]
pub conditional: bool,
#[serde(default = "default_true")]
pub chain: bool,
}
impl Default for CrudSpec {
fn default() -> Self {
Self {
create: true,
read: true,
vread: false,
update: true,
delete: true,
patch: false,
history_instance: false,
history_type: false,
conditional: false,
chain: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchSpec {
#[serde(default = "default_true")]
pub single_param: bool,
#[serde(default)]
pub combined_params: bool,
#[serde(default)]
pub modifiers: bool,
#[serde(default)]
pub prefixes: bool,
#[serde(default)]
pub chained: bool,
#[serde(default)]
pub include: bool,
#[serde(default)]
pub revinclude: bool,
#[serde(default)]
pub result_params: Vec<String>,
#[serde(default)]
pub negative_values: Vec<String>,
}
impl Default for SearchSpec {
fn default() -> Self {
Self {
single_param: true,
combined_params: false,
modifiers: false,
prefixes: false,
chained: false,
include: false,
revinclude: false,
result_params: vec![],
negative_values: vec![],
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationSpec {
#[serde(default = "default_true")]
pub enabled: bool,
}
impl Default for OperationSpec {
fn default() -> Self {
Self { enabled: true }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NegativeSpec {
#[serde(default = "default_true")]
pub undeclared_interactions: bool,
#[serde(default = "default_true")]
pub invalid_bodies: bool,
#[serde(default)]
pub malformed_requests: bool,
#[serde(default)]
pub auth_errors: bool,
#[serde(default)]
pub version_conflicts: bool,
}
impl Default for NegativeSpec {
fn default() -> Self {
Self {
undeclared_interactions: true,
invalid_bodies: true,
malformed_requests: false,
auth_errors: false,
version_conflicts: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EdgeCaseSpec {
#[serde(default = "default_true")]
pub boundary_values: bool,
#[serde(default = "default_true")]
pub special_characters: bool,
#[serde(default)]
pub large_payloads: bool,
#[serde(default)]
pub concurrent_operations: bool,
#[serde(default)]
pub dangling_references: bool,
}
impl Default for EdgeCaseSpec {
fn default() -> Self {
Self {
boundary_values: true,
special_characters: true,
large_payloads: false,
concurrent_operations: false,
dangling_references: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConformanceSpec {
#[serde(default = "default_true")]
pub profile_validation: bool,
#[serde(default = "default_true")]
pub must_support: bool,
}
impl Default for ConformanceSpec {
fn default() -> Self {
Self {
profile_validation: true,
must_support: true,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SecuritySpec {
#[serde(default)]
pub auth_required: bool,
#[serde(default)]
pub cors: bool,
#[serde(default)]
pub info_leak: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PerformanceSpec {
#[serde(default)]
pub response_time: bool,
#[serde(default)]
pub pagination: bool,
}
fn default_true() -> bool {
true
}
fn default_data_count() -> u64 {
3
}