Repository: TBD54566975/ssi-service
Pull request #203 (2022-12-08 21:29:51)

[OSE-261] Parent now a required argument when fetching operations
# Overview
The `GetOperations` endpoint had an argument called `Parent` which didn't have any effect. This PR implements the expected behavior. 

# Description
The `Parent` argument is now required. Additionally, I change the implementation of the operation service slightly so that operations with different response types end up in different buckets. 

# How Has This Been Tested?
Unit tests

# Checklist

Before submitting this PR, please make sure:

- [x] I have read the CONTRIBUTING document.
- [x] My code is consistent with the rest of the project 
- [x] I have tagged the relevant reviewers and/or interested parties
- [x] I have updated the READMEs and other documentation of affected packages

## References
N/A


codecov-commenter: # [Codecov](https://codecov.io/gh/TBD54566975/ssi-service/pull/203?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975) Report
> Merging [#203](https://codecov.io/gh/TBD54566975/ssi-service/pull/203?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975) (ddb31ce) into [main](https://codecov.io/gh/TBD54566975/ssi-service/commit/8a1a7ff31c2f35eb0b7e17e64c51a429ae669ab3?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975) (8a1a7ff) will **decrease** coverage by `0.06%`.
> The diff coverage is `0.00%`.

```diff
@@            Coverage Diff             @@
##             main     #203      +/-   ##
==========================================
- Coverage   22.07%   22.01%   -0.07%     
==========================================
  Files          26       26              
  Lines        2147     2153       +6     
==========================================
  Hits          474      474              
- Misses       1597     1603       +6     
  Partials       76       76              
```


| [Impacted Files](https://codecov.io/gh/TBD54566975/ssi-service/pull/203?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975) | Coverage Δ | |
|---|---|---|
| [pkg/server/router/operation.go](https://codecov.io/gh/TBD54566975/ssi-service/pull/203/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975#diff-cGtnL3NlcnZlci9yb3V0ZXIvb3BlcmF0aW9uLmdv) | `0.00% <0.00%> (ø)` | |
| [pkg/server/router/presentation.go](https://codecov.io/gh/TBD54566975/ssi-service/pull/203/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975#diff-cGtnL3NlcnZlci9yb3V0ZXIvcHJlc2VudGF0aW9uLmdv) | `4.10% <ø> (ø)` | |
| [pkg/service/operation/model.go](https://codecov.io/gh/TBD54566975/ssi-service/pull/203/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975#diff-cGtnL3NlcnZpY2Uvb3BlcmF0aW9uL21vZGVsLmdv) | `75.00% <0.00%> (-25.00%)` | :arrow_down: |
| [pkg/service/operation/service.go](https://codecov.io/gh/TBD54566975/ssi-service/pull/203/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975#diff-cGtnL3NlcnZpY2Uvb3BlcmF0aW9uL3NlcnZpY2UuZ28=) | `0.00% <0.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TBD54566975)


Patch:
diff --git a/doc/swagger.yaml b/doc/swagger.yaml
index f0685a4..0052fcb 100644
--- a/doc/swagger.yaml
+++ b/doc/swagger.yaml
@@ -796,7 +796,7 @@ definitions:
         description: Whether this operation has finished.
         type: boolean
       id:
-        description: The name of the resource related to this operation. E.g. "/presentation/submissions/<uuid>"
+        description: The name of the resource related to this operation. E.g. "/presentations/submissions/<uuid>"
         type: string
       result:
         $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.OperationResult'
@@ -1348,7 +1348,7 @@ definitions:
         description: Whether this operation has finished.
         type: boolean
       id:
-        description: The name of the resource related to this operation. E.g. "/presentation/submissions/<uuid>"
+        description: The name of the resource related to this operation. E.g. "/presentations/submissions/<uuid>"
         type: string
       result:
         $ref: '#/definitions/pkg_server_router.OperationResult'
@@ -1615,7 +1615,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetHealthCheckResponse'
+            $ref: '#/definitions/pkg_server_router.GetHealthCheckResponse'
       summary: Health Check
       tags:
       - HealthCheck
@@ -1661,7 +1661,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetCredentialsResponse'
+            $ref: '#/definitions/pkg_server_router.GetCredentialsResponse'
         "400":
           description: Bad request
           schema:
@@ -1683,14 +1683,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateCredentialRequest'
+          $ref: '#/definitions/pkg_server_router.CreateCredentialRequest'
       produces:
       - application/json
       responses:
         "201":
           description: Created
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateCredentialResponse'
+            $ref: '#/definitions/pkg_server_router.CreateCredentialResponse'
         "400":
           description: Bad request
           schema:
@@ -1747,7 +1747,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetCredentialResponse'
+            $ref: '#/definitions/pkg_server_router.GetCredentialResponse'
         "400":
           description: Bad request
           schema:
@@ -1772,7 +1772,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetCredentialStatusResponse'
+            $ref: '#/definitions/pkg_server_router.GetCredentialStatusResponse'
         "400":
           description: Bad request
           schema:
@@ -1790,14 +1790,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.UpdateCredentialStatusRequest'
+          $ref: '#/definitions/pkg_server_router.UpdateCredentialStatusRequest'
       produces:
       - application/json
       responses:
         "201":
           description: Created
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.UpdateCredentialStatusResponse'
+            $ref: '#/definitions/pkg_server_router.UpdateCredentialStatusResponse'
         "400":
           description: Bad request
           schema:
@@ -1826,7 +1826,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetCredentialStatusListResponse'
+            $ref: '#/definitions/pkg_server_router.GetCredentialStatusListResponse'
         "400":
           description: Bad request
           schema:
@@ -1845,14 +1845,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.VerifyCredentialRequest'
+          $ref: '#/definitions/pkg_server_router.VerifyCredentialRequest'
       produces:
       - application/json
       responses:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.VerifyCredentialResponse'
+            $ref: '#/definitions/pkg_server_router.VerifyCredentialResponse'
         "400":
           description: Bad request
           schema:
@@ -2006,7 +2006,7 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/pkg_server_router.StoreKeyRequest'
+          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.StoreKeyRequest'
       produces:
       - application/json
       responses:
@@ -2040,7 +2040,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/pkg_server_router.GetKeyDetailsResponse'
+            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetKeyDetailsResponse'
         "400":
           description: Bad request
           schema:
@@ -2073,7 +2073,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetManifestsResponse'
+            $ref: '#/definitions/pkg_server_router.GetManifestsResponse'
         "400":
           description: Bad request
           schema:
@@ -2095,14 +2095,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateManifestRequest'
+          $ref: '#/definitions/pkg_server_router.CreateManifestRequest'
       produces:
       - application/json
       responses:
         "201":
           description: Created
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateManifestResponse'
+            $ref: '#/definitions/pkg_server_router.CreateManifestResponse'
         "400":
           description: Bad request
           schema:
@@ -2159,7 +2159,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetManifestResponse'
+            $ref: '#/definitions/pkg_server_router.GetManifestResponse'
         "400":
           description: Bad request
           schema:
@@ -2179,7 +2179,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetApplicationsResponse'
+            $ref: '#/definitions/pkg_server_router.GetApplicationsResponse'
         "400":
           description: Bad request
           schema:
@@ -2202,14 +2202,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.SubmitApplicationRequest'
+          $ref: '#/definitions/pkg_server_router.SubmitApplicationRequest'
       produces:
       - application/json
       responses:
         "201":
           description: Created
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.SubmitApplicationResponse'
+            $ref: '#/definitions/pkg_server_router.SubmitApplicationResponse'
         "400":
           description: Bad request
           schema:
@@ -2266,7 +2266,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetApplicationResponse'
+            $ref: '#/definitions/pkg_server_router.GetApplicationResponse'
         "400":
           description: Bad request
           schema:
@@ -2286,7 +2286,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetResponsesResponse'
+            $ref: '#/definitions/pkg_server_router.GetResponsesResponse'
         "400":
           description: Bad request
           schema:
@@ -2343,7 +2343,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetResponseResponse'
+            $ref: '#/definitions/pkg_server_router.GetResponseResponse'
         "400":
           description: Bad request
           schema:
@@ -2589,7 +2589,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetSchemasResponse'
+            $ref: '#/definitions/pkg_server_router.GetSchemasResponse'
         "500":
           description: Internal server error
           schema:
@@ -2607,14 +2607,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateSchemaRequest'
+          $ref: '#/definitions/pkg_server_router.CreateSchemaRequest'
       produces:
       - application/json
       responses:
         "201":
           description: Created
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.CreateSchemaResponse'
+            $ref: '#/definitions/pkg_server_router.CreateSchemaResponse'
         "400":
           description: Bad request
           schema:
@@ -2671,7 +2671,7 @@ paths:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetSchemaResponse'
+            $ref: '#/definitions/pkg_server_router.GetSchemaResponse'
         "400":
           description: Bad request
           schema:
@@ -2690,14 +2690,14 @@ paths:
         name: request
         required: true
         schema:
-          $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.VerifySchemaRequest'
+          $ref: '#/definitions/pkg_server_router.VerifySchemaRequest'
       produces:
       - application/json
       responses:
         "200":
           description: OK
           schema:
-            $ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.VerifySchemaResponse'
+            $ref: '#/definitions/pkg_server_router.VerifySchemaResponse'
         "400":
           description: Bad request
           schema:
diff --git a/pkg/server/router/operation.go b/pkg/server/router/operation.go
index f0e667d..20c6535 100644
--- a/pkg/server/router/operation.go
+++ b/pkg/server/router/operation.go
@@ -66,6 +66,7 @@ const FilterCharacterLimit = 1024
 
 func (r GetOperationsRequest) ToServiceRequest() (operation.GetOperationsRequest, error) {
 	var opReq operation.GetOperationsRequest
+	opReq.Parent = r.Parent
 
 	declarations, err := filtering.NewDeclarations(
 		filtering.DeclareFunction(filtering.FunctionEquals,
diff --git a/pkg/server/router/presentation.go b/pkg/server/router/presentation.go
index b115f5e..c41c050 100644
--- a/pkg/server/router/presentation.go
+++ b/pkg/server/router/presentation.go
@@ -219,7 +219,7 @@ func (r CreateSubmissionRequest) toServiceRequest() (*presentation.CreateSubmiss
 }
 
 type Operation struct {
-	// The name of the resource related to this operation. E.g. "/presentation/submissions/<uuid>"
+	// The name of the resource related to this operation. E.g. "/presentations/submissions/<uuid>"
 	ID string `json:"id"`
 
 	// Whether this operation has finished.
diff --git a/pkg/service/operation/model.go b/pkg/service/operation/model.go
index 801ceab..959734c 100644
--- a/pkg/service/operation/model.go
+++ b/pkg/service/operation/model.go
@@ -1,6 +1,7 @@
 package operation
 
 import (
+	"github.com/TBD54566975/ssi-sdk/util"
 	"go.einride.tech/aip/filtering"
 	"strings"
 )
@@ -27,10 +28,14 @@ func SubmissionID(opID string) string {
 }
 
 type GetOperationsRequest struct {
-	Parent string
+	Parent string `validate:"required"`
 	Filter filtering.Filter
 }
 
+func (r GetOperationsRequest) Validate() error {
+	return util.NewValidator().Struct(r)
+}
+
 type GetOperationsResponse struct {
 	Operations []Operation
 }
diff --git a/pkg/service/operation/service.go b/pkg/service/operation/service.go
index 7ad0c60..01cef07 100644
--- a/pkg/service/operation/service.go
+++ b/pkg/service/operation/service.go
@@ -33,7 +33,11 @@ func (s Service) Status() framework.Status {
 }
 
 func (s Service) GetOperations(request GetOperationsRequest) (*GetOperationsResponse, error) {
-	ops, err := s.storage.GetOperations(request.Filter)
+	if err := request.Validate(); err != nil {
+		return nil, errors.Wrap(err, "invalid request")
+	}
+
+	ops, err := s.storage.GetOperations(request.Parent, request.Filter)
 	if err != nil {
 		return nil, errors.Wrap(err, "fetching ops from storage")
 	}
diff --git a/pkg/service/operation/storage/bolt.go b/pkg/service/operation/storage/bolt.go
index 4c39c8f..d28eb5e 100644
--- a/pkg/service/operation/storage/bolt.go
+++ b/pkg/service/operation/storage/bolt.go
@@ -1,18 +1,40 @@
 package storage
 
 import (
+	"fmt"
 	"github.com/goccy/go-json"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"github.com/tbd54566975/ssi-service/internal/util"
 	"github.com/tbd54566975/ssi-service/pkg/storage"
 	"go.einride.tech/aip/filtering"
+	"strings"
 )
 
 const (
-	namespace = "operation"
+	namespace  = "operation"
+	submission = "submission"
 )
 
+const SubmissionParentResource = "/presentations/submissions"
+
+func namespaceFromID(id string) string {
+	i := strings.LastIndex(id, "/")
+	if i == -1 {
+		return ""
+	}
+	return namespaceFromParent(id[:i])
+}
+
+func namespaceFromParent(parent string) string {
+	switch parent {
+	case SubmissionParentResource:
+		return fmt.Sprintf("%s_%s", namespace, submission)
+	default:
+		return ""
+	}
+}
+
 type BoltOperationStorage struct {
 	db *storage.BoltDB
 }
@@ -26,11 +48,11 @@ func (b BoltOperationStorage) StoreOperation(op StoredOperation) error {
 	if err != nil {
 		return util.LoggingErrorMsgf(err, "marshalling operation with id: %s", id)
 	}
-	return b.db.Write(namespace, id, jsonBytes)
+	return b.db.Write(namespaceFromID(id), id, jsonBytes)
 }
 
 func (b BoltOperationStorage) GetOperation(id string) (*StoredOperation, error) {
-	jsonBytes, err := b.db.Read(namespace, id)
+	jsonBytes, err := b.db.Read(namespaceFromID(id), id)
 	if err != nil {
 		return nil, util.LoggingErrorMsgf(err, "reading operation with id: %s", id)
 	}
@@ -44,8 +66,8 @@ func (b BoltOperationStorage) GetOperation(id string) (*StoredOperation, error)
 	return &stored, nil
 }
 
-func (b BoltOperationStorage) GetOperations(filter filtering.Filter) ([]StoredOperation, error) {
-	operations, err := b.db.ReadAll(namespace)
+func (b BoltOperationStorage) GetOperations(parent string, filter filtering.Filter) ([]StoredOperation, error) {
+	operations, err := b.db.ReadAll(namespaceFromParent(parent))
 	if err != nil {
 		return nil, util.LoggingErrorMsgf(err, "could not get all operations")
 	}
@@ -74,7 +96,7 @@ func (b BoltOperationStorage) GetOperations(filter filtering.Filter) ([]StoredOp
 }
 
 func (b BoltOperationStorage) DeleteOperation(id string) error {
-	if err := b.db.Delete(namespace, id); err != nil {
+	if err := b.db.Delete(namespaceFromID(id), id); err != nil {
 		return util.LoggingErrorMsgf(err, "deleting operation: %s", id)
 	}
 	return nil
diff --git a/pkg/service/operation/storage/storage.go b/pkg/service/operation/storage/storage.go
index a4e90d3..dae9f9b 100644
--- a/pkg/service/operation/storage/storage.go
+++ b/pkg/service/operation/storage/storage.go
@@ -33,7 +33,7 @@ func (s StoredOperation) FilterVariablesMap() map[string]interface{} {
 type Storage interface {
 	StoreOperation(op StoredOperation) error
 	GetOperation(id string) (*StoredOperation, error)
-	GetOperations(filter filtering.Filter) ([]StoredOperation, error)
+	GetOperations(parent string, filter filtering.Filter) ([]StoredOperation, error)
 	DeleteOperation(id string) error
 }
 
diff --git a/pkg/service/presentation/service.go b/pkg/service/presentation/service.go
index b8867c4..7e6bf39 100644
--- a/pkg/service/presentation/service.go
+++ b/pkg/service/presentation/service.go
@@ -184,7 +184,7 @@ func (s Service) CreateSubmission(request CreateSubmissionRequest) (*operation.O
 		return nil, errors.Wrap(err, "could not store presentation")
 	}
 
-	opID := fmt.Sprintf("presentations/submissions/%s", storedSubmission.Submission.ID)
+	opID := fmt.Sprintf("%s/%s", opstorage.SubmissionParentResource, storedSubmission.Submission.ID)
 	storedOp := opstorage.StoredOperation{
 		ID:   opID,
 		Done: false,


Test patch:
diff --git a/pkg/server/server_operation_test.go b/pkg/server/server_operation_test.go
index 7e01420..99235ee 100644
--- a/pkg/server/server_operation_test.go
+++ b/pkg/server/server_operation_test.go
@@ -22,7 +22,9 @@ func TestOperationsAPI(t *testing.T) {
 			assert.NoError(t, err)
 			opRouter := setupOperationsRouter(t, s)
 
-			request := router.GetOperationsRequest{}
+			request := router.GetOperationsRequest{
+				Parent: "/presentations/submissions",
+			}
 			value := newRequestValue(t, request)
 			req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/operations", value)
 			w := httptest.NewRecorder()
@@ -47,7 +49,9 @@ func TestOperationsAPI(t *testing.T) {
 			holderSigner2, holderDID2 := getSigner(t)
 			submissionOp2 := createSubmission(t, pRouter, def.PresentationDefinition.ID, VerifiableCredential(), holderDID2, holderSigner2)
 
-			request := router.GetOperationsRequest{}
+			request := router.GetOperationsRequest{
+				Parent: "/presentations/submissions",
+			}
 			value := newRequestValue(t, request)
 			req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/operations", value)
 			w := httptest.NewRecorder()
@@ -79,6 +83,7 @@ func TestOperationsAPI(t *testing.T) {
 			_ = createSubmission(t, pRouter, def.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
 
 			request := router.GetOperationsRequest{
+				Parent: "/presentations/submissions",
 				Filter: "done = false",
 			}
 			value := newRequestValue(t, request)
@@ -104,6 +109,7 @@ func TestOperationsAPI(t *testing.T) {
 			_ = createSubmission(t, pRouter, def.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
 
 			request := router.GetOperationsRequest{
+				Parent: "/presentations/submissions",
 				Filter: "done = true",
 			}
 			value := newRequestValue(t, request)
@@ -116,6 +122,30 @@ func TestOperationsAPI(t *testing.T) {
 			assert.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
 			assert.Empty(t, resp.Operations)
 		})
+
+		t.Run("Returns zero operations when wrong parent is specified", func(t *testing.T) {
+			s, err := storage.NewBoltDB()
+			assert.NoError(t, err)
+			pRouter := setupPresentationRouter(t, s)
+			opRouter := setupOperationsRouter(t, s)
+
+			def := createPresentationDefinition(t, pRouter)
+			holderSigner, holderDID := getSigner(t)
+			_ = createSubmission(t, pRouter, def.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
+
+			request := router.GetOperationsRequest{
+				Parent: "/presentations/other",
+			}
+			value := newRequestValue(t, request)
+			req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/operations", value)
+			w := httptest.NewRecorder()
+
+			assert.NoError(t, opRouter.GetOperations(newRequestContext(), w, req))
+
+			var resp router.GetOperationsResponse
+			assert.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
+			assert.Empty(t, resp.Operations)
+		})
 	})
 
 }