diff --git a/contracts/job_registry/src/lib.rs b/contracts/job_registry/src/lib.rs index 47c89477..b633a1c5 100644 --- a/contracts/job_registry/src/lib.rs +++ b/contracts/job_registry/src/lib.rs @@ -323,18 +323,48 @@ impl JobRegistryContract { Ok(()) } - pub fn get_job(env: Env, job_id: u64) -> JobRecord { + /// Retrieves a job record by its ID. + /// + /// This is a view function that provides the full state of a job, + /// including its status, client, and assigned freelancer. + /// + /// # Arguments + /// * `env` - The Soroban environment + /// * `job_id` - The unique identifier of the job + /// + /// # Returns + /// * `Ok(JobRecord)` - The job record if found + /// * `Err(JobRegistryError::JobNotFound)` - If the job ID does not exist + pub fn get_job(env: Env, job_id: u64) -> Result { env.storage() .persistent() .get(&DataKey::Job(job_id)) - .expect("job not found") + .ok_or(JobRegistryError::JobNotFound) } - pub fn get_bids(env: Env, job_id: u64) -> Vec { - env.storage() + /// Retrieves all bids for a specific job. + /// + /// This is a view function that returns the history of all bids + /// submitted for a given job. If a job exists but has no bids, + /// an empty vector is returned. + /// + /// # Arguments + /// * `env` - The Soroban environment + /// * `job_id` - The unique identifier of the job + /// + /// # Returns + /// * `Ok(Vec)` - A vector of all bids submitted for the job + /// * `Err(JobRegistryError::JobNotFound)` - If the job ID does not exist + pub fn get_bids(env: Env, job_id: u64) -> Result, JobRegistryError> { + if !env.storage().persistent().has(&DataKey::Job(job_id)) { + return Err(JobRegistryError::JobNotFound); + } + + Ok(env + .storage() .persistent() .get(&DataKey::Bids(job_id)) - .unwrap_or_else(|| Vec::new(&env)) + .unwrap_or_else(|| Vec::new(&env))) } pub fn get_deliverable(env: Env, job_id: u64) -> Bytes { @@ -810,4 +840,24 @@ mod test { let empty_deliverable = Bytes::from_slice(&env, b""); cc.submit_deliverable(&1u64, &freelancer, &empty_deliverable); } + + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_get_job_not_found() { + let env = Env::default(); + let contract_id = env.register_contract(None, JobRegistryContract); + let cc = JobRegistryContractClient::new(&env, &contract_id); + + cc.get_job(&999u64); + } + + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_get_bids_job_not_found() { + let env = Env::default(); + let contract_id = env.register_contract(None, JobRegistryContract); + let cc = JobRegistryContractClient::new(&env, &contract_id); + + cc.get_bids(&999u64); + } } diff --git a/contracts/reputation/src/lib.rs b/contracts/reputation/src/lib.rs index 7daead64..d9a31cd1 100644 --- a/contracts/reputation/src/lib.rs +++ b/contracts/reputation/src/lib.rs @@ -93,7 +93,13 @@ impl ReputationContract { // call JobRegistry.get_job(job_id) and decode into local JobRecord let get_sym = Symbol::new(&env, "get_job"); let args = soroban_sdk::vec![&env, job_id.into_val(&env)]; - let job: JobRecord = env.invoke_contract::(®istry_addr, &get_sym, args); + let job: JobRecord = env + .invoke_contract::>( + ®istry_addr, + &get_sym, + args, + ) + .unwrap(); // verify job is completed (ratings only allowed after completion) assert!(job.status == JobStatus::Completed, "job not completed"); diff --git a/docs/contracts/job_registry.md b/docs/contracts/job_registry.md index 7979fd1d..eba1a1f2 100644 --- a/docs/contracts/job_registry.md +++ b/docs/contracts/job_registry.md @@ -28,6 +28,35 @@ The `JobRegistry` contract manages job postings, bid submissions, bid acceptance - `Unauthorized` (3): caller is not the job's client. - `BidNotFound` (6): selected freelancer did not submit a bid. -### Notes - This implementation strengthens trustlessness by ensuring bid acceptance can only succeed for bidders who actually participated in the auction. + +## `get_job` + +### Purpose + +`get_job` is a view function that retrieves the full record of a specific job. + +### Behavior + +- Retrieves the `JobRecord` from persistent storage. +- Returns the job details if it exists. + +### Errors + +- `JobNotFound` (1): The specified job ID does not exist. + +## `get_bids` + +### Purpose + +`get_bids` is a view function that retrieves all bids submitted for a specific job. + +### Behavior + +- Verifies the job exists. +- Retrieves the list of `BidRecord`s associated with the job. +- Returns an empty list if the job exists but has no bids. + +### Errors + +- `JobNotFound` (1): The specified job ID does not exist.