Skip to content

Commit

Permalink
Make entity ids mandatory in Bulk update/patch requests
Browse files Browse the repository at this point in the history
  • Loading branch information
gbuisson committed Dec 11, 2024
1 parent 51e43f5 commit b6b974a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/ctia/bulk/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
:responses {200 {:schema (s/maybe (bulk.schemas/BulkActionsRefs services))}}
:summary "UPDATE many entities at once"
:query-params [{wait_for :- (describe s/Bool "wait for updated entities to be available for search") nil}]
:body [bulk (describe (bulk.schemas/BulkUpdate services) "a new Bulk Update object")]
:body [bulk (describe (bulk.schemas/BulkUpdate services) "a Bulk Update object")]
:description (common/capabilities->description capabilities)
:capabilities capabilities
:auth-identity auth-identity
Expand Down
54 changes: 34 additions & 20 deletions src/ctia/bulk/schemas.clj
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,34 @@
s/Keyword s/Any})])

(defn entity-schema
[{:keys [plural] :as entity} sch services]
(let [bulk-schema
(if (keyword? sch)
[(s/maybe
(let [ent-schema (get entity sch)]
(if (fn? ent-schema) (ent-schema services) ent-schema)))]
sch)]
{(-> plural
name
(str/replace #"-" "_")
keyword)
bulk-schema}))
([entity sch services]
(entity-schema entity sch services {}))
([{:keys [plural] :as entity} sch services {:keys [required-ids?]}]
(let [bulk-schema
(if (keyword? sch)
[(s/maybe
(let [ent-schema (get entity sch)]
(cond-> (if (fn? ent-schema)
(ent-schema services) ent-schema)
required-ids? (st/required-keys [:id]))))]
(if required-ids?
(st/required-keys sch :id)
sch))]
{(-> plural
name
(str/replace #"-" "_")
keyword)
bulk-schema})))

(defn entities-bulk-schema
[entities sch services]
(st/optional-keys
(->> (vals entities)
(remove :no-bulk?)
(map #(entity-schema % sch services))
(apply merge {}))))
([entities sch services]
(entities-bulk-schema entities sch services {}))
([entities sch services opts]
(st/optional-keys
(->> (vals entities)
(remove :no-bulk?)
(map #(entity-schema % sch services opts))
(apply merge {})))))

(s/defschema EntityError
"Error related to one entity of the bulk"
Expand Down Expand Up @@ -74,7 +82,7 @@
(let [patchable-entities (into {}
(filter #(:can-patch? (second %)))
(get-entities services))]
(entities-bulk-schema patchable-entities :partial-schema services)))
(entities-bulk-schema patchable-entities :partial-schema services {:required-ids? true})))

(s/defn BulkRefs :- (s/protocol s/Schema)
[services :- GetEntitiesServices]
Expand All @@ -91,7 +99,13 @@
[services :- GetEntitiesServices]
(entities-bulk-schema (get-entities services) :new-schema services))

(def BulkUpdate NewBulk)
(s/defn BulkUpdate :- (s/protocol s/Schema)
"Returns NewBulk schema without disabled entities and required ids"
[services :- GetEntitiesServices]
(entities-bulk-schema (get-entities services)
:new-schema
services
{:required-ids? true}))

(def NewBulkDelete BulkRefs)

Expand Down
44 changes: 34 additions & 10 deletions test/ctia/bulk/routes_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@
:headers {"Authorization" "45c1f5e3f05d0"})
bulk-ids (:parsed-body response)
show-props (get-http-show (app->HTTPShowServices app))]

(is (= 201 (:status response)))

(doseq [type (keys new-bulk)]
Expand All @@ -327,10 +328,10 @@
(count (get bulk-ids type))))))
(testing "created events are generated"
(let [expected-created-ids (mapcat val (dissoc bulk-ids :tempids))]
(check-events event-store
ident
expected-created-ids
:record-created)))
(check-events event-store
ident
expected-created-ids
:record-created)))
(testing "GET /ctia/bulk"
(let [{status :status
response :parsed-body}
Expand Down Expand Up @@ -387,6 +388,29 @@
(concat indicator-ids sighting-ids note-ids)
:record-updated)))

(testing "PUT /ctia/bulk without ids"
(let [update-fn (fn [record] (-> record
(assoc :source "updated")
(dissoc :id)))
indicator-ids (:indicators bulk-ids)
sighting-ids (:sightings bulk-ids)
note-ids (:notes bulk-ids)
update-bulk {:indicators (map (fn [_] (update-fn (mk-new-indicator 0))) indicator-ids)
:sightings (map (fn [_] (update-fn (mk-new-sighting 0))) sighting-ids)
:notes (map (fn [_] (update-fn (mk-new-note 0))) note-ids)}
expected-update {:indicators {:updated (set indicator-ids)}
:sightings {:updated (set sighting-ids)}
:notes {:updated (set note-ids)}}
{:keys [status parsed-body]} (PUT app
bulk-url
:form-params update-bulk
:headers {"Authorization" "45c1f5e3f05d0"})]
(is (= 400 status))
(is (= parsed-body
{:errors {:notes (repeat 7 {:id 'missing-required-key})
:indicators (repeat 7 {:id 'missing-required-key})
:sightings (repeat 7 {:id 'missing-required-key})}}))))

(testing "PATCH /ctia/bulk"
(let [incident-ids (:incidents bulk-ids)
sighting-ids (:sightings bulk-ids)
Expand Down Expand Up @@ -422,13 +446,13 @@
{k (take 2 ids)}))
(dissoc bulk-ids :tempids))
expected-deleted (into {}
(map (fn [[k ids]]
{k {:deleted ids}}))
delete-bulk-query)
(map (fn [[k ids]]
{k {:deleted ids}}))
delete-bulk-query)
expected-not-found (into {}
(map (fn [[k ids]]
{k {:errors {:not-found ids}}}))
delete-bulk-query)
(map (fn [[k ids]]
{k {:errors {:not-found ids}}}))
delete-bulk-query)
delete-bulk-url "ctia/bulk?wait_for=true"
{delete-status-1 :status delete-res-1 :parsed-body}
(DELETE app
Expand Down

0 comments on commit b6b974a

Please sign in to comment.