diff --git a/search-app/docs/api.md b/search-app/docs/api.md
index f87d85dfc7..b43e2f0abc 100644
--- a/search-app/docs/api.md
+++ b/search-app/docs/api.md
@@ -3857,7 +3857,7 @@ curl -XDELETE -i -H "Content-Type: application/json" -H "Authorization: Bearer X
{"concept_id": "C1200000006-PROV1"},
{"concept_id": "C1200000007-PROV1"}]'
-HTTP/1.1 400 Bad Request
+HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=ISO-8859-1
Content-Length: 168
@@ -3890,7 +3890,7 @@ Content-Length: 168
]
```
-On occasions when tag dissociation cannot be processed at all due to invalid input, tag dissociation request will return a failure status code with the appropriate error message.
+On occasions when tag dissociation cannot be processed at all due to invalid input, tag dissociation request will return status code 200 with appropriate error messages for each failed dissociation. If all the dissociations in the request fail, a 400 failure status code will be returned.
#### Dissociating a Tag from Collections by query
@@ -4653,7 +4653,7 @@ curl -XPOST -i -H "Content-Type: application/json" -H "Authorization: Bearer XXX
'[{"concept_id": "C1200000005-PROV1", "data": {"order_option": "OO1200445588-PROV1"}},
{"concept_id": "C1200000006-PROV1"}]'
-HTTP/1.1 400 BAD REQUEST
+HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 168
@@ -4678,20 +4678,21 @@ Content-Length: 168
]
```
-On occasions when service association cannot be processed at all due to invalid input, service association request will return a failure status code with the appropriate error message.
+On occasions when service association cannot be processed at all due to invalid input, service association request will return status code 200 with appropriate error messages for each failed association. If all the associations in the request fail, a 400 failure status code will be returned.
#### Service Dissociation
A service identified by its concept id can be dissociated from collections through a list of collection concept revisions similar to service association requests.
Service dissociation requires that user has update permission on INGEST_MANAGEMENT_ACL for either the collection's provider, or the service's provider.
+Service dissociation
```
curl -XDELETE -i -H "Content-Type: application/json" -H "Authorization: Bearer XXXXX" %CMR-ENDPOINT%/services/S1200000008-PROV1/associations -d \
'[{"concept_id": "C1200000005-PROV1"},
{"concept_id": "C1200000006-PROV1"},
{"concept_id": "C1200000007-PROV1"}]'
-HTTP/1.1 400 BAD REQUEST
+HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 168
@@ -4732,7 +4733,7 @@ Content-Length: 168
]
```
-On occasions when service dissociation cannot be processed at all due to invalid input, service dissociation request will return a failure status code with the appropriate error message.
+On occasions when service dissociation cannot be processed at all due to invalid input, service dissociation request will return status code 200 with appropriate error messages for each failed dissociation. If all the dissociations in the request fail, a 400 failure status code will be returned.
### Tool
@@ -5030,7 +5031,7 @@ curl -XPOST -i -H "Content-Type: application/json" -H "Authorization: Bearer XXX
'[{"concept_id": "C1200000005-PROV1"},
{"concept_id": "C1200000006-PROV1"}]'
-HTTP/1.1 400 BAD REQUEST
+HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 168
@@ -5064,7 +5065,7 @@ Content-Length: 168
]
```
-On occasions when tool association cannot be processed at all due to invalid input, tool association request will return a failure status code with the appropriate error message.
+On occasions when tool association cannot be processed at all due to invalid input, tool association request will return status code 200 with appropriate error messages for each failed association. If all the associations in the request fail, a 400 failure status code will be returned.
#### Tool Dissociation
@@ -5077,7 +5078,7 @@ curl -XDELETE -i -H "Content-Type: application/json" -H "Authorization: Bearer X
{"concept_id": "C1200000006-PROV1"},
{"concept_id": "C1200000007-PROV1"}]'
-HTTP/1.1 400 BAD REQUEST
+HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 168
@@ -5118,7 +5119,7 @@ Content-Length: 168
]
```
-On occasions when tool dissociation cannot be processed at all due to invalid input, tool dissociation request will return a failure status code with the appropriate error message.
+On occasions when tool dissociation cannot be processed at all due to invalid input, tool dissociation request will return status code 200 with appropriate error messages for each failed dissociation. If all the associations in the request fail, a 400 failure status code will be returned.
### Subscription
diff --git a/search-app/src/cmr/search/api/association.clj b/search-app/src/cmr/search/api/association.clj
index 721a730737..ef0d62e92a 100644
--- a/search-app/src/cmr/search/api/association.clj
+++ b/search-app/src/cmr/search/api/association.clj
@@ -24,10 +24,10 @@
:body (json/generate-string (util/snake-case-data data))
:headers {"Content-Type" mt/json}}))
-(defn- results-contain-errors?
- "Returns true if the results contain :errors"
+(defn- all-results-contain-errors?
+ "Returns true if the all results contain :errors"
[results]
- (seq (filter #(some? (:errors %)) results)))
+ (not (some #(nil? (:errors %)) results)))
(defn association-results->status-code
"Check for concept-types requiring error status to be returned. This is currently :service and :variable
@@ -35,7 +35,7 @@
any are errors are present. Otherwise it will return 200"
[concept-type results]
(if (some #{concept-type} '(:variable :service :tool))
- (if (results-contain-errors? results)
+ (if (all-results-contain-errors? results)
400
200)
200))
diff --git a/search-app/src/cmr/search/api/generic_association.clj b/search-app/src/cmr/search/api/generic_association.clj
index 0731d3b011..6e40ee5074 100644
--- a/search-app/src/cmr/search/api/generic_association.clj
+++ b/search-app/src/cmr/search/api/generic_association.clj
@@ -24,15 +24,15 @@
:body (json/generate-string (util/snake-case-data data))
:headers {"Content-Type" mt/json}}))
-(defn- results-contain-errors?
- "Returns true if the results contain :errors"
+(defn- all-results-contain-errors?
+ "Returns true if every single result contains :errors"
[results]
- (seq (filter #(some? (:errors %)) results)))
+ (not (some #(nil? (:errors %)) results)))
(defn- results->status-code
"Return status code depending on if results contains error."
[results]
- (if (results-contain-errors? results)
+ (if (all-results-contain-errors? results)
400
200))
diff --git a/system-int-test/src/cmr/system_int_test/utils/tool_util.clj b/system-int-test/src/cmr/system_int_test/utils/tool_util.clj
index a832c2d9f0..4ac996ab56 100644
--- a/system-int-test/src/cmr/system_int_test/utils/tool_util.clj
+++ b/system-int-test/src/cmr/system_int_test/utils/tool_util.clj
@@ -314,6 +314,11 @@
(is (= (set (map :concept-id expected-colls))
(set colls)))))
+(defn assert-tool-dissociation-response-ok?
+ "Assert the tool association response when status code is 200 is correct."
+ [coll-tool-associations response]
+ (assert-tool-association-response-ok? coll-tool-associations response false))
+
(defn assert-tool-dissociation-bad-request
"Assert the tool association response when status code is 400 is correct."
[coll-tool-associations response]
diff --git a/system-int-test/test/cmr/system_int_test/search/misc/association_test.clj b/system-int-test/test/cmr/system_int_test/search/misc/association_test.clj
index cc89c02b94..4365cf4a14 100644
--- a/system-int-test/test/cmr/system_int_test/search/misc/association_test.clj
+++ b/system-int-test/test/cmr/system_int_test/search/misc/association_test.clj
@@ -78,10 +78,10 @@
:revision-id coll2-revision-id}])
tla2-concept-id (some #(when (:tool-association %) (get-in % [:tool-association :concept-id]))
(:body assoc-response2))]
- (is (= {:status 400, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id tla1-concept-id, :revision-id 1}, :associated-item {:concept-id coll2-concept-id, :revision-id coll2-revision-id}}]}
+ (is (= {:status 200, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id tla1-concept-id, :revision-id 1}, :associated-item {:concept-id coll2-concept-id, :revision-id coll2-revision-id}}]}
assoc-response1))
- (is (= {:status 400, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id tla2-concept-id, :revision-id 1}, :associated-item {:concept-id coll2-concept-id, :revision-id coll2-revision-id}}]}
+ (is (= {:status 200, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id tla2-concept-id, :revision-id 1}, :associated-item {:concept-id coll2-concept-id, :revision-id coll2-revision-id}}]}
assoc-response2))))
(testing "dissociation-permission-test"
@@ -118,7 +118,7 @@
[{:concept-id coll1-concept-id}
{:concept-id coll2-concept-id
:revision-id coll2-revision-id}])]
- (is (= {:status 400, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] or provider of service/tool to delete the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id (last tla1-concept-ids), :revision-id 3}, :associated-item {:concept-id coll2-concept-id, :revision-id 1}}]}
+ (is (= {:status 200, :body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] or provider of service/tool to delete the association.")], :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id (last tla1-concept-ids), :revision-id 3}, :associated-item {:concept-id coll2-concept-id, :revision-id 1}}]}
dissoc-response1))
(is (= {:status 200, :body [{:tool-association {:concept-id (first tla2-concept-ids), :revision-id 2}, :associated-item {:concept-id coll1-concept-id}} {:tool-association {:concept-id (last tla2-concept-ids), :revision-id 3}, :associated-item {:concept-id coll2-concept-id, :revision-id 1}}]}
@@ -143,14 +143,14 @@
:revision-id coll2-revision-id}])
sa2-concept-id (some #(when (:service-association %) (get-in % [:service-association :concept-id]))
(:body assoc-response2))]
- (is (= {:status 400
+ (is (= {:status 200
:body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")]
:associated-item {:concept-id coll1-concept-id}}
{:service-association {:concept-id sa1-concept-id, :revision-id 1}
:associated-item {:concept-id coll2-concept-id, :revision-id coll2-revision-id}}]}
assoc-response1))
- (is (= {:status 400
+ (is (= {:status 200
:body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] to make the association.")]
:associated-item {:concept-id coll1-concept-id}}
{:service-association {:concept-id sa2-concept-id, :revision-id 1}
@@ -191,7 +191,7 @@
[{:concept-id coll1-concept-id}
{:concept-id coll2-concept-id
:revision-id coll2-revision-id}])]
- (is (= {:status 400
+ (is (= {:status 200
:body [{:errors [(str "User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [" coll1-concept-id "] or provider of service/tool to delete the association.")]
:associated-item {:concept-id coll1-concept-id}}
{:service-association {:concept-id (last sa1-concept-ids), :revision-id 3}
diff --git a/system-int-test/test/cmr/system_int_test/search/service/service_association_test.clj b/system-int-test/test/cmr/system_int_test/search/service/service_association_test.clj
index 324b2e6533..afe12dae9c 100644
--- a/system-int-test/test/cmr/system_int_test/search/service/service_association_test.clj
+++ b/system-int-test/test/cmr/system_int_test/search/service/service_association_test.clj
@@ -104,7 +104,7 @@
(let [response (association-util/associate-by-concept-ids
token concept-id [{:concept-id c2-p1}
{:concept-id "C100-P5"}])]
- (service-util/assert-service-association-bad-request
+ (service-util/assert-service-association-response-ok?
{[c2-p1] {:concept-id "SA1200000028-CMR"
:revision-id 1}
["C100-P5"] {:errors ["User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [C100-P5] to make the association."]}}
@@ -302,7 +302,7 @@
{:concept-id (:concept-id coll2) :revision-id 1} ;; success
{:concept-id (:concept-id coll3)}])] ;; no service association
- (service-util/assert-service-dissociation-bad-request
+ (service-util/assert-service-dissociation-response-ok?
{["C100-P5"] {:errors ["Collection [C100-P5] does not exist or is not visible."]}
["C1200000012-PROV1"] {:concept-id "SA1200000016-CMR" :revision-id 2}
["C1200000013-PROV1" 1] {:concept-id "SA1200000017-CMR" :revision-id 2}
diff --git a/system-int-test/test/cmr/system_int_test/search/tool/tool_association_test.clj b/system-int-test/test/cmr/system_int_test/search/tool/tool_association_test.clj
index 1f4459c6ae..4a497349c3 100644
--- a/system-int-test/test/cmr/system_int_test/search/tool/tool_association_test.clj
+++ b/system-int-test/test/cmr/system_int_test/search/tool/tool_association_test.clj
@@ -103,7 +103,7 @@
(let [response (association-util/associate-by-concept-ids
token concept-id [{:concept-id c2-p1}
{:concept-id "C100-P5"}])]
- (tool-util/assert-tool-association-bad-request
+ (tool-util/assert-tool-association-response-ok?
{[c2-p1] {:concept-id "TLA1200000028-CMR"
:revision-id 1}
["C100-P5"] {:errors ["User doesn't have update permission on INGEST_MANAGEMENT_ACL for provider of collection [C100-P5] to make the association."]}}
@@ -301,7 +301,7 @@
{:concept-id (:concept-id coll2) :revision-id 1} ;; success
{:concept-id (:concept-id coll3)}])] ;; no tool association
- (tool-util/assert-tool-dissociation-bad-request
+ (tool-util/assert-tool-dissociation-response-ok?
{["C100-P5"] {:errors ["Collection [C100-P5] does not exist or is not visible."]}
["C1200000012-PROV1"] {:concept-id "TLA1200000016-CMR" :revision-id 2}
["C1200000013-PROV1" 1] {:concept-id "TLA1200000017-CMR" :revision-id 2}