Skip to content

Commit

Permalink
Joint programs
Browse files Browse the repository at this point in the history
  • Loading branch information
mdemare committed Jan 29, 2025
1 parent 3cbf641 commit e0ea1b5
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 41 deletions.
4 changes: 3 additions & 1 deletion src/nl/surf/eduhub_rio_mapper/commands/processing.clj
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@
(ooapi.loader/load-entities validating-loader request)))))

(defn- make-updater-resolve-phase [{:keys [resolver]}]
(fn resolve-phase [{::ooapi/keys [type id] :keys [institution-oin action] ::rio/keys [opleidingscode] :as request}]
(fn resolve-phase [{:keys [institution-oin action]
::ooapi/keys [type id]
::rio/keys [opleidingscode] :as request}]
{:pre [institution-oin]}
(let [resolve-eduspec (= type "education-specification")
edu-id (updated-handler/education-specification-id request)
Expand Down
49 changes: 25 additions & 24 deletions src/nl/surf/eduhub_rio_mapper/ooapi/loader.clj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
[nl.surf.eduhub-rio-mapper.specs.ooapi :as ooapi]
[nl.surf.eduhub-rio-mapper.specs.program :as program]
[nl.surf.eduhub-rio-mapper.specs.request :as request]
[nl.surf.eduhub-rio-mapper.specs.rio :as rio]
[nl.surf.eduhub-rio-mapper.utils.http-utils :as http-utils]
[nl.surf.eduhub-rio-mapper.utils.ooapi :as ooapi-utils]))

Expand Down Expand Up @@ -163,33 +164,33 @@
"Loads ooapi entity, including associated offerings and education specification, if applicable."
[loader {::ooapi/keys [type] :as request}]
(let [entity (loader request)
rio-consumer (ooapi-utils/extract-rio-consumer (:consumers entity))
joint-program? (= "true" (str (:jointProgram rio-consumer)))
offerings (load-offerings loader request)
education-specification (if (= type "education-specification")
entity
eduspec-type (cond
joint-program?
"program"

(= type "education-specification")
(:educationSpecificationType entity)

:else
(-> request
(assoc ::ooapi/type "education-specification"
::ooapi/id (ooapi-base/education-specification-id entity))
(loader)))]
(loader)
:educationSpecificationType))]

(when (and (not= type "education-specification")
(= "program" (:educationSpecificationType education-specification)))
(= "program" eduspec-type))
(validate-entity entity ::program/ProgramType "ProgramType")
(validate-entity (ooapi-utils/extract-rio-consumer (:consumers entity)) ::program/ProgramConsumerType "ProgramConsumerType"))
(assoc request
::ooapi/entity (assoc entity :offerings offerings)
::ooapi/education-specification education-specification)))

(defn wrap-load-entities
"Middleware for loading and validating ooapi entitites.
Gets ooapi/type and ooapi/id from the request and fetches the given
entity + its related offerings and its education-specification.
The resulting entity is passed along as ::ooapi/entity
with :offerings. The related education-specification is passed
as ::ooapi/education-specification."
[f ooapi-loader]
(let [loader (validating-loader ooapi-loader)]
(fn wrapped-load-entities [{:keys [::ooapi/type] :as request}]
(if (= "relation" type)
(f request)
(->> request (load-entities loader) (f))))))
(validate-entity rio-consumer ::program/ProgramConsumerType "ProgramConsumerType"))
(cond-> request
true
(assoc
::ooapi/entity (assoc entity :offerings offerings)
::ooapi/education-specification-type eduspec-type)

joint-program?
(assoc
::rio/opleidingscode (:educationUnitCode rio-consumer)))))
2 changes: 1 addition & 1 deletion src/nl/surf/eduhub_rio_mapper/rio/aangeboden_opleiding.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
(ns nl.surf.eduhub-rio-mapper.rio.aangeboden-opleiding
(:require [clojure.string :as str]
[nl.surf.eduhub-rio-mapper.rio.helper :as rio-helper]
[nl.surf.eduhub-rio-mapper.specs.rio :as rio]
[nl.surf.eduhub-rio-mapper.utils.ooapi :as ooapi-utils])
(:import [java.time Period Duration]))

Expand Down Expand Up @@ -176,6 +175,7 @@
(defn ->aangeboden-opleiding
"Converts a program or course into the right kind of AangebodenOpleiding."
[course-program ooapi-type opleidingscode education-specification-type]
{:pre [(string? education-specification-type)]}
(-> (course-program-adapter course-program opleidingscode ooapi-type)
rio-helper/wrapper-periodes-cohorten
(rio-helper/->xml (education-specification-type-mapping education-specification-type))))
8 changes: 5 additions & 3 deletions src/nl/surf/eduhub_rio_mapper/rio/updated_handler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
id
(ooapi-base/education-specification-id entity)))

;; Used in test only
(defn wrap-resolver
"Get the RIO opleidingscode and aangeboden opleiding code for the given entity.
Expand All @@ -60,9 +61,10 @@
(defn update-mutation
"Returned object conforms to ::Mutation/mutation-response."
[{:keys [institution-oin args]
::ooapi/keys [id entity type education-specification]
::ooapi/keys [id entity type education-specification-type]
::rio/keys [opleidingscode aangeboden-opleiding-code]}]
{:post [(s/valid? ::mutation/mutation-response %)]}
{:pre [(or (not= type "program") education-specification-type)]
:post [(s/valid? ::mutation/mutation-response %)]}
(assert institution-oin)
(if (and (not (#{"education-specification" "relation"} type))
(not opleidingscode))
Expand Down Expand Up @@ -98,7 +100,7 @@
{:action "aanleveren_aangebodenOpleiding"
:ooapi entity
:sender-oin institution-oin
:rio-sexp [(aangeboden-opl/->aangeboden-opleiding entity :program opleidingscode (:educationSpecificationType education-specification))]}
:rio-sexp [(aangeboden-opl/->aangeboden-opleiding entity :program opleidingscode education-specification-type)]}

"relation"
(let [[object-code valid-from valid-to] args]
Expand Down
11 changes: 8 additions & 3 deletions src/nl/surf/eduhub_rio_mapper/specs/program.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
(:require [clojure.spec.alpha :as s]
[nl.surf.eduhub-rio-mapper.ooapi.enums :as enums]
[nl.surf.eduhub-rio-mapper.re-spec :refer [re-spec text-spec]]
[nl.surf.eduhub-rio-mapper.specs.common :as common]))
[nl.surf.eduhub-rio-mapper.specs.common :as common]
[nl.surf.eduhub-rio-mapper.specs.rio :as rio]))

(s/def ::abbreviation
(text-spec 1 40))
Expand All @@ -32,6 +33,8 @@
(s/def ::description ::common/LongLanguageTypedStrings)
(s/def ::educationLocationCode string?)
(s/def ::educationSpecification ::common/uuid)
(s/def ::educationUnitCode ::rio/OpleidingsEenheidID-v01)
(s/def ::jointProgram boolean?)
(s/def ::firstStartDate ::common/date)
(s/def ::foreignPartner string?)
(s/def ::foreignPartners (s/coll-of ::foreignPartner))
Expand Down Expand Up @@ -82,13 +85,13 @@
(s/def ::program
(s/keys :req-un [::programId
::consumers
::educationSpecification
::name
::validFrom]
:opt-un [::abbreviation
::children
::description
::common/duration
::educationSpecification
::link
::modeOfStudy
::parent
Expand All @@ -104,4 +107,6 @@

(s/def ::ProgramConsumerType
(s/keys :req-un [::propaedeuticPhase
::studyChoiceCheck]))
::studyChoiceCheck]
:opt-un [::educationUnitCode
::jointProgram]))
80 changes: 73 additions & 7 deletions test/nl/surf/eduhub_rio_mapper/mapper_integration_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.test :refer :all]
[nl.surf.eduhub-rio-mapper.ooapi.loader :as ooapi.loader]
[nl.surf.eduhub-rio-mapper.rio.mutator :as mutator]
[nl.surf.eduhub-rio-mapper.rio.updated-handler :as updated-handler]
[nl.surf.eduhub-rio-mapper.specs.ooapi :as ooapi]
[nl.surf.eduhub-rio-mapper.test-helper :refer [load-json]]
[nl.surf.eduhub-rio-mapper.utils.keystore :as keystore]))
[nl.surf.eduhub-rio-mapper.test-helper :as helper :refer [load-json]]
[nl.surf.eduhub-rio-mapper.utils.keystore :as keystore])
(:import [clojure.lang ExceptionInfo]))

(def institution-oin "123O321")
(def rio-opleidingsid "1234O1234")
Expand Down Expand Up @@ -57,7 +57,7 @@
(updated-handler/wrap-resolver $ (fn rio-resolver [ootype _id _oin] (if (= ootype "education-specification")
rio-opleidingsid
"12345678-9abc-def0-1234-56789abcdef0")))
(ooapi.loader/wrap-load-entities $ ooapi-loader)))
(helper/wrap-load-entities $ ooapi-loader)))

;; resolver takes sender-oin and ooapi-id and returns code
;; mutator takes {:keys [action sender-oin rio-sexp]} returns json
Expand All @@ -74,9 +74,10 @@
{:pre [(some? xml-response)]}
(binding [client/request (constantly {:status 200 :body xml-response})]
(let [handle-updated (mock-handle-updated ooapi-loader)
mutation (handle-updated {::ooapi/id ooapi-id
::ooapi/type ooapi-type
:institution-oin institution-oin})]
mutation (handle-updated {::ooapi/id ooapi-id
::ooapi/type ooapi-type
:institution-oin institution-oin
::ooapi/education-specification-type "program"})]
{:result (mutator/mutate! mutation (:rio-config config))
:mutation mutation})))

Expand Down Expand Up @@ -135,6 +136,71 @@
(is (= [:duo:cohortcode "34333"] (get-in mutation [:rio-sexp 0 9 1])))
(is (= "true" (-> actual :aanleveren_aangebodenOpleiding_response :requestGoedgekeurd)))))

(deftest test-make-fake-joint-program
(let [ooapi-loader (mock-ooapi-loader {:program-course "fixtures/ooapi/integration-program-0.json"
:offerings "fixtures/ooapi/integration-program-offerings-0.json"})
ooapi-loader #(-> (ooapi-loader %)
(update-in [:consumers 1] merge {:jointProgram true}))
r (simulate-upsert ooapi-loader
(slurp (io/resource "fixtures/rio/integratie-program-0.xml"))
"program")
actual (:result r)
mutation (:mutation r)]
(is (nil? (:errors actual)))
(is (= [:duo:opleidingseenheidSleutel "1234O1234"]
(first
(filter (fn [v] (and (vector? v) (= (first v) :duo:opleidingseenheidSleutel)))
(-> mutation :rio-sexp first)))))
(is (= "true" (-> actual :aanleveren_aangebodenOpleiding_response :requestGoedgekeurd)))))

(deftest test-make-joint-program
(let [ooapi-loader (mock-ooapi-loader {:program-course "fixtures/ooapi/integration-program-0.json"
:offerings "fixtures/ooapi/integration-program-offerings-0.json"})
ooapi-loader #(-> (ooapi-loader %)
(update-in [:consumers 1] merge {:jointProgram true
:educationUnitCode "1234O4323"}))
r (simulate-upsert ooapi-loader
(slurp (io/resource "fixtures/rio/integratie-program-0.xml"))
"program")
actual (:result r)
mutation (:mutation r)]
(is (nil? (:errors actual)))
(is (= [:duo:opleidingseenheidSleutel "1234O4323"]
(first
(filter (fn [v] (and (vector? v) (= (first v) :duo:opleidingseenheidSleutel)))
(-> mutation :rio-sexp first)))))
(is (= "true" (-> actual :aanleveren_aangebodenOpleiding_response :requestGoedgekeurd)))))

(deftest test-make-joint-program-without-eduspec
(let [ooapi-loader (mock-ooapi-loader {:program-course "fixtures/ooapi/integration-program-0.json"
:offerings "fixtures/ooapi/integration-program-offerings-0.json"})
ooapi-loader #(-> (ooapi-loader %)
(update-in [:consumers 1] merge {:jointProgram true
:educationUnitCode "1234O4323"})
(dissoc :educationSpecification))
r (simulate-upsert ooapi-loader
(slurp (io/resource "fixtures/rio/integratie-program-0.xml"))
"program")
actual (:result r)
mutation (:mutation r)]
(is (nil? (:errors actual)))
(is (= [:duo:opleidingseenheidSleutel "1234O4323"]
(first
(filter (fn [v] (and (vector? v) (= (first v) :duo:opleidingseenheidSleutel)))
(-> mutation :rio-sexp first)))))
(is (= "true" (-> actual :aanleveren_aangebodenOpleiding_response :requestGoedgekeurd)))))

(deftest test-make-joint-program-invalid-code
(let [ooapi-loader (mock-ooapi-loader {:program-course "fixtures/ooapi/integration-program-0.json"
:offerings "fixtures/ooapi/integration-program-offerings-0.json"})
ooapi-loader #(-> (ooapi-loader %)
(update-in [:consumers 1] merge {:jointProgram true
:educationUnitCode "ZAZA"}))]
(is (thrown? ExceptionInfo
(simulate-upsert ooapi-loader
(slurp (io/resource "fixtures/rio/integratie-program-0.xml"))
"program")))))

(deftest test-remove-eduspec-0
(let [actual (simulate-delete "education-specification"
(slurp (io/resource "fixtures/rio/integration-deletion-eduspec-0.xml")))]
Expand Down
3 changes: 2 additions & 1 deletion test/nl/surf/eduhub_rio_mapper/rio_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
[nl.surf.eduhub-rio-mapper.rio.opleidingseenheid :as opl-eenh]
[nl.surf.eduhub-rio-mapper.rio.updated-handler :as updated-handler]
[nl.surf.eduhub-rio-mapper.specs.ooapi :as ooapi]
[nl.surf.eduhub-rio-mapper.test-helper :as helper]
[nl.surf.eduhub-rio-mapper.utils.keystore :as keystore]
[nl.surf.eduhub-rio-mapper.utils.soap :as soap]
[nl.surf.eduhub-rio-mapper.utils.xml-utils :as xml-utils])
Expand Down Expand Up @@ -61,7 +62,7 @@
(updated-handler/wrap-resolver (fn [ootype _ _] (if (= "education-specification" ootype)
"1009O1234"
"12345678-9abc-def0-1234-56789abcdef0")))
(ooapi.loader/wrap-load-entities ooapi.loader/ooapi-file-loader)
(helper/wrap-load-entities ooapi.loader/ooapi-file-loader)
(clients-info/wrap-client-info [{:client-id "rio-mapper-dev.jomco.nl"
:institution-schac-home "demo06.test.surfeduhub.nl"
:institution-oin "0000000700025BE00000"}])))
Expand Down
12 changes: 11 additions & 1 deletion test/nl/surf/eduhub_rio_mapper/test_helper.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
[clojure.java.io :as io]
[clojure.pprint :refer [pprint]]
[clojure.string :as str]
[clojure.test :refer :all])
[clojure.test :refer :all]
[nl.surf.eduhub-rio-mapper.ooapi.loader :as ooapi.loader]
[nl.surf.eduhub-rio-mapper.specs.ooapi :as-alias ooapi])
(:import
[java.io PushbackReader]))

Expand All @@ -33,6 +35,14 @@
slurp
(json/read-str :key-fn keyword)))

(defn wrap-load-entities
[f ooapi-loader]
(let [loader (ooapi.loader/validating-loader ooapi-loader)]
(fn wrapped-load-entities [{:keys [::ooapi/type] :as request}]
(f
(cond->> request
(not= "relation" type) (ooapi.loader/load-entities loader))))))

(defn wait-while-predicate [predicate val-atom max-sec]
(loop [ttl (* max-sec 10)]
(when (and (pos? ttl) (predicate @val-atom))
Expand Down

0 comments on commit e0ea1b5

Please sign in to comment.