Bug: [FEATURE] Implement `RefundInterface` for `MockDb`



Spin out from #172. Please refer to that issue for more information.
diff --git a/crates/router/src/db/refund.rs b/crates/router/src/db/refund.rs
index e3ff8b8dc6d..bb40bd76429 100644
--- a/crates/router/src/db/refund.rs
+++ b/crates/router/src/db/refund.rs
@@ -1,4 +1,4 @@
-use storage_models::errors::DatabaseError;
+use storage_models::{errors::DatabaseError, refund::RefundUpdateInternal};
 
 use super::MockDb;
 use crate::{
@@ -604,12 +604,21 @@ mod storage {
 impl RefundInterface for MockDb {
     async fn find_refund_by_internal_reference_id_merchant_id(
         &self,
-        _internal_reference_id: &str,
-        _merchant_id: &str,
+        internal_reference_id: &str,
+        merchant_id: &str,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> CustomResult<storage_types::Refund, errors::StorageError> {
-        // [#172]: Implement function for `MockDb`
-        Err(errors::StorageError::MockDbError)?
+        let refunds = self.refunds.lock().await;
+        refunds
+            .iter()
+            .find(|refund| {
+                refund.merchant_id == merchant_id
+                    && refund.internal_reference_id == internal_reference_id
+            })
+            .cloned()
+            .ok_or_else(|| {
+                errors::StorageError::DatabaseError(DatabaseError::NotFound.into()).into()
+            })
     }
 
     async fn insert_refund(
@@ -670,12 +679,24 @@ impl RefundInterface for MockDb {
 
     async fn update_refund(
         &self,
-        _this: storage_types::Refund,
-        _refund: storage_types::RefundUpdate,
+        this: storage_types::Refund,
+        refund: storage_types::RefundUpdate,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> CustomResult<storage_types::Refund, errors::StorageError> {
-        // [#172]: Implement function for `MockDb`
-        Err(errors::StorageError::MockDbError)?
+        self.refunds
+            .lock()
+            .await
+            .iter_mut()
+            .find(|refund| this.refund_id == refund.refund_id)
+            .map(|r| {
+                let refund_updated = RefundUpdateInternal::from(refund).create_refund(r.clone());
+                *r = refund_updated.clone();
+                refund_updated
+            })
+            .ok_or_else(|| {
+                errors::StorageError::ValueNotFound("cannot find refund to update".to_string())
+                    .into()
+            })
     }
 
     async fn find_refund_by_merchant_id_refund_id(
@@ -719,23 +740,34 @@ impl RefundInterface for MockDb {
 
     async fn find_refund_by_payment_id_merchant_id(
         &self,
-        _payment_id: &str,
-        _merchant_id: &str,
+        payment_id: &str,
+        merchant_id: &str,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> CustomResult<Vec<storage_types::Refund>, errors::StorageError> {
-        // [#172]: Implement function for `MockDb`
-        Err(errors::StorageError::MockDbError)?
+        let refunds = self.refunds.lock().await;
+
+        Ok(refunds
+            .iter()
+            .filter(|refund| refund.merchant_id == merchant_id && refund.payment_id == payment_id)
+            .cloned()
+            .collect::<Vec<_>>())
     }
 
     #[cfg(feature = "olap")]
     async fn filter_refund_by_constraints(
         &self,
-        _merchant_id: &str,
+        merchant_id: &str,
         _refund_details: &api_models::refunds::RefundListRequest,
         _storage_scheme: enums::MerchantStorageScheme,
-        _limit: i64,
+        limit: i64,
     ) -> CustomResult<Vec<storage_models::refund::Refund>, errors::StorageError> {
-        // [#172]: Implement function for `MockDb`
-        Err(errors::StorageError::MockDbError)?
+        let refunds = self.refunds.lock().await;
+
+        Ok(refunds
+            .iter()
+            .filter(|refund| refund.merchant_id == merchant_id)
+            .take(usize::try_from(limit).unwrap_or(usize::MAX))
+            .cloned()
+            .collect::<Vec<_>>())
     }
 }
diff --git a/crates/storage_models/src/refund.rs b/crates/storage_models/src/refund.rs
index ae590532d1f..b0b1f03f200 100644
--- a/crates/storage_models/src/refund.rs
+++ b/crates/storage_models/src/refund.rs
@@ -115,6 +115,22 @@ pub struct RefundUpdateInternal {
     refund_error_code: Option<String>,
 }
 
+impl RefundUpdateInternal {
+    pub fn create_refund(self, source: Refund) -> Refund {
+        Refund {
+            connector_refund_id: self.connector_refund_id,
+            refund_status: self.refund_status.unwrap_or_default(),
+            sent_to_gateway: self.sent_to_gateway.unwrap_or_default(),
+            refund_error_message: self.refund_error_message,
+            refund_arn: self.refund_arn,
+            metadata: self.metadata,
+            refund_reason: self.refund_reason,
+            refund_error_code: self.refund_error_code,
+            ..source
+        }
+    }
+}
+
 impl From<RefundUpdate> for RefundUpdateInternal {
     fn from(refund_update: RefundUpdate) -> Self {
         match refund_update {

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [X] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!-- 
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
The main motivation is to have MockDb stubs, help to void mocking, and invocation of external database api's.
For more information check https://github.com/juspay/hyperswitch/issues/172

Fixes #1276 


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [X] I formatted the code `cargo +nightly fmt --all`
- [X] I addressed lints thrown by `cargo clippy`
- [X] I reviewed submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable

