from abc import ABC, abstractmethod from typing import Any, List, Optional from models.generation_strategy import GenerationStrategy from models.openapi import Schema class AffectedElement(ABC): def __init__( self, key: str, reference: Schema, positive_value: Optional[Any] = None ): self.key = key self.reference = reference self.positive_value = positive_value @property @abstractmethod def generation_strategies(self) -> List[GenerationStrategy]: pass class EnumAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [GenerationStrategy.INVALID_ENUM, GenerationStrategy.NULL_VALUE] class LeafAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [GenerationStrategy.INVALID_KEY, GenerationStrategy.MISSING_KEY] class NonLeafAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: if self.key == "body": return [GenerationStrategy.EXTRA_KEY] if self.reference.type == "array": return [GenerationStrategy.INVALID_KEY, GenerationStrategy.MISSING_KEY] # For object return [ GenerationStrategy.MISSING_KEY, GenerationStrategy.INVALID_KEY, GenerationStrategy.EXTRA_KEY, ] # Add more affected element classes as needed class DigitAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.NULL_VALUE, GenerationStrategy.EXCEED_MAX, GenerationStrategy.BELOW_MIN, ] class StringAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.NULL_VALUE, GenerationStrategy.EXCEED_MAX, GenerationStrategy.BELOW_MIN, ] class ArrayAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.NULL_VALUE, GenerationStrategy.EXCEED_MAX, GenerationStrategy.BELOW_MIN, ] class ObjectAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.NULL_VALUE, GenerationStrategy.EXCEED_MAX, # GenerationStrategy.BELOW_MIN, # TODO: cooperate with required attributes ] class AuthAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.RANDOM_VALUE, ] class BizEnumAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: if self.key == "method": return [ GenerationStrategy.RANDOM_VALUE, GenerationStrategy.BUSINESS_ENUM, ] return [ GenerationStrategy.NULL_VALUE, GenerationStrategy.RANDOM_VALUE, GenerationStrategy.MISSING_KEY, GenerationStrategy.BUSINESS_ENUM, ] class PathParamAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: return [ GenerationStrategy.NULL_VALUE, GenerationStrategy.RANDOM_VALUE, ] class QueryParamAffectedElement(AffectedElement): @property def generation_strategies(self) -> List[GenerationStrategy]: if self.key == "query_params.projectId": return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.INVALID_KEY, GenerationStrategy.FORBIDDEN_403, ] return [ GenerationStrategy.INVALID_TYPE, GenerationStrategy.INVALID_KEY, ]