Repository: meilisearch/meilisearch
File: crates/meilisearch/tests/common/server.rs (Rust)

Code before:

    pub async fn create_dump(&self) -> (Value, StatusCode) {
        self.service.post("/dumps", json!(null)).await
    }

    pub async fn create_snapshot(&self) -> (Value, StatusCode) {
        self.service.post("/snapshots", json!(null)).await
    }

    pub async fn index_swap(&self, value: Value) -> (Value, StatusCode) {
        self.service.post("/swap-indexes", value).await
    }

    pub async fn cancel_tasks(&self, value: &str) -> (Value, StatusCode) {
        self.service.post(format!("/tasks/cancel?{}", value), json!(null)).await
    }

    pub async fn delete_tasks(&self, value: &str) -> (Value, StatusCode) {
        self.service.delete(format!("/tasks?{}", value)).await
    }

    pub async fn wait_task(&self, update_id: u64) -> Value {
        Server::<Shared>::_wait_task(async |url| self.service.get(url).await, update_id).await
    }

    pub(super) async fn _wait_task<F>(request_fn: F, update_id: u64) -> Value
    where
        F: AsyncFnOnce(String) -> (Value, StatusCode) + Copy,
    {
        // try several times to get status, or panic to not wait forever
        let url = format!("/tasks/{update_id}");
        let max_attempts = 400; // 200 seconds in total, 0.5secs per attempt

        for i in 0..max_attempts {
            let (response, status_code) = request_fn(url.clone()).await;
            assert_eq!(200, status_code, "response: {response}");

            if response["status"] == "succeeded" || response["status"] == "failed" {
                return response;
            }

            // wait 0.5 second.
            sleep(Duration::from_millis(500)).await;

            if i == max_attempts - 1 {
                dbg!(response);
            }
        }
        panic!("Timeout waiting for update id");
    }


Review comment (refactor):
This method is needed because `common::index` needs to use it.
I guess this was the reason for the duplicated method in both files.

Code after:

    pub async fn create_dump(&self) -> (Value, StatusCode) {
        self.service.post("/dumps", json!(null)).await
    }

    pub async fn create_snapshot(&self) -> (Value, StatusCode) {
        self.service.post("/snapshots", json!(null)).await
    }

    pub async fn index_swap(&self, value: Value) -> (Value, StatusCode) {
        self.service.post("/swap-indexes", value).await
    }

    pub async fn cancel_tasks(&self, value: &str) -> (Value, StatusCode) {
        self.service.post(format!("/tasks/cancel?{}", value), json!(null)).await
    }

    pub async fn delete_tasks(&self, value: &str) -> (Value, StatusCode) {
        self.service.delete(format!("/tasks?{}", value)).await
    }

    pub async fn wait_task(&self, update_id: u64) -> Value {
        // try several times to get status, or panic to not wait forever
        let url = format!("/tasks/{update_id}");
        let max_attempts = 400; // 200 seconds in total, 0.5secs per attempt

        for i in 0..max_attempts {
            let (response, status_code) = self.service.get(url.clone()).await;
            assert_eq!(200, status_code, "response: {response}");

            if response["status"] == "succeeded" || response["status"] == "failed" {
                return response;
            }

            // wait 0.5 second.
            sleep(Duration::from_millis(500)).await;

            if i == max_attempts - 1 {
                dbg!(response);
            }
        }
        panic!("Timeout waiting for update id");
    }

    pub async fn get_task(&self, update_id: u64) -> (Value, StatusCode) {
        let url = format!("/tasks/{}", update_id);
        self.service.get(url).await
    }

    pub async fn get_batch(&self, batch_id: u32) -> (Value, StatusCode) {
        let url = format!("/batches/{}", batch_id);