diff --git a/etp-backend/src/main/clj/solita/etp/schema/valvonta_kaytto.clj b/etp-backend/src/main/clj/solita/etp/schema/valvonta_kaytto.clj index 1a47ac1f4..358925fe4 100644 --- a/etp-backend/src/main/clj/solita/etp/schema/valvonta_kaytto.clj +++ b/etp-backend/src/main/clj/solita/etp/schema/valvonta_kaytto.clj @@ -9,11 +9,12 @@ (assoc schema :id common-schema/Key :valvonta-id common-schema/Key)) (def ValvontaQuery - {(schema/optional-key :valvoja-id) common-schema/Key - (schema/optional-key :has-valvoja) schema/Bool - (schema/optional-key :include-closed) schema/Bool - (schema/optional-key :keyword) schema/Str - (schema/optional-key :toimenpidetype-id) common-schema/Key}) + {(schema/optional-key :valvoja-id) common-schema/Key + (schema/optional-key :has-valvoja) schema/Bool + (schema/optional-key :include-closed) schema/Bool + (schema/optional-key :keyword) schema/Str + (schema/optional-key :toimenpidetype-id) common-schema/Key + (schema/optional-key :asiakirjapohja-id) common-schema/Key}) (def ValvontaSave {:rakennustunnus (schema/maybe common-schema/Rakennustunnus) @@ -43,7 +44,7 @@ (def Template (assoc valvonta-schema/Template - :tiedoksi schema/Bool)) + :tiedoksi schema/Bool)) (def OsapuoliBase (schema-tools/merge {:rooli-id (schema/maybe common-schema/Key) @@ -69,15 +70,15 @@ (-> ToimenpideAdd (dissoc (schema/optional-key :bypass-asha)) (assoc - :id common-schema/Key - :diaarinumero (schema/maybe schema/Str) - :author common-schema/Kayttaja - :create-time common-schema/Instant - :publish-time common-schema/Instant - :filename (schema/maybe schema/Str) - :valvonta-id common-schema/Key - :henkilot [Henkilo] - :yritykset [Yritys]))) + :id common-schema/Key + :diaarinumero (schema/maybe schema/Str) + :author common-schema/Kayttaja + :create-time common-schema/Instant + :publish-time common-schema/Instant + :filename (schema/maybe schema/Str) + :valvonta-id common-schema/Key + :henkilot [Henkilo] + :yritykset [Yritys]))) (def LastToimenpide (schema-tools/select-keys Toimenpide @@ -101,7 +102,7 @@ :description schema/Str}) (def ExistingValvonta - {:id common-schema/Key + {:id common-schema/Key :end-time (schema/maybe common-schema/Instant)}) (def Toimenpidetyypit diff --git a/etp-backend/src/main/clj/solita/etp/service/valvonta_kaytto.clj b/etp-backend/src/main/clj/solita/etp/service/valvonta_kaytto.clj index a2dc073a7..d0295dbe1 100644 --- a/etp-backend/src/main/clj/solita/etp/service/valvonta_kaytto.clj +++ b/etp-backend/src/main/clj/solita/etp/service/valvonta_kaytto.clj @@ -37,6 +37,7 @@ :include-closed false :keyword nil :toimenpidetype-id nil + :asiakirjapohja-id nil :limit 10 :offset 0}) diff --git a/etp-backend/src/main/sql/solita/etp/db/valvonta-kaytto.sql b/etp-backend/src/main/sql/solita/etp/db/valvonta-kaytto.sql index 6b3c8fc7f..82f626e20 100644 --- a/etp-backend/src/main/sql/solita/etp/db/valvonta-kaytto.sql +++ b/etp-backend/src/main/sql/solita/etp/db/valvonta-kaytto.sql @@ -40,6 +40,7 @@ where not valvonta.deleted and (last_toimenpide.id is null or last_toimenpide.type_id <> 5 or :include-closed) and (:toimenpidetype-id::int is null or :toimenpidetype-id = last_toimenpide.type_id) and + (:asiakirjapohja-id::int is null or :asiakirjapohja-id = last_toimenpide.template_id) and (:keyword::text is null or valvonta.rakennustunnus ilike :keyword or valvonta.katuosoite ilike :keyword or @@ -85,6 +86,7 @@ where not valvonta.deleted and (last_toimenpide.id is null or last_toimenpide.type_id <> 5 or :include-closed) and (:toimenpidetype-id::int is null or :toimenpidetype-id = last_toimenpide.type_id) and + (:asiakirjapohja-id::int is null or :asiakirjapohja-id = last_toimenpide.template_id) and (:keyword::text is null or valvonta.rakennustunnus ilike :keyword or valvonta.katuosoite ilike :keyword or diff --git a/etp-backend/src/test/clj/solita/etp/test_data/kayttaja.clj b/etp-backend/src/test/clj/solita/etp/test_data/kayttaja.clj index 78d279515..7a19f190f 100644 --- a/etp-backend/src/test/clj/solita/etp/test_data/kayttaja.clj +++ b/etp-backend/src/test/clj/solita/etp/test_data/kayttaja.clj @@ -26,7 +26,7 @@ (defn generate-updates [n] (take n (map #(generators/complete {:henkilotunnus %1 - :email %2} + :email %2} kayttaja-schema/KayttajaUpdate) (generators/unique-henkilotunnukset n) (generators/unique-emails n)))) @@ -43,3 +43,18 @@ (map #(assoc % :rooli 2)) insert! first)) + +(defn insert-virtu-paakayttaja! + "Inserts a new paakayttaja that can be used with headers below, and returns its id. + + Headers: + x-amzn-oidc-accesstoken eyJraWQiOiJ0ZXN0LWtpZCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJwYWFrYXl0dGFqYUBzb2xpdGEuZmkiLCJ0b2tlbl91c2UiOiJhY2Nlc3MiLCJzY29wZSI6Im9wZW5pZCIsImF1dGhfdGltZSI6MTU4MzIzMDk2OSwiaXNzIjoiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3NvbGl0YS9ldHAtY29yZS9mZWF0dXJlL0FFLTQzLWF1dGgtaGVhZGVycy1oYW5kbGluZy9ldHAtYmFja2VuZC9zcmMvbWFpbi9yZXNvdXJjZXMiLCJleHAiOjE4OTM0NTYwMDAsImlhdCI6MTU4MzQxMzQyNCwidmVyc2lvbiI6MiwianRpIjoiNWZkZDdhMjktN2VlYS00ZjNkLWE3YTYtYzIyODQyNmY2MTJiIiwiY2xpZW50X2lkIjoidGVzdC1jbGllbnRfaWQiLCJ1c2VybmFtZSI6InRlc3QtdXNlcm5hbWUifQ.PY5_jWcdxhCyn2EpFpss7Q0R3_xH1PvHi4mxDLorpppHnciGT2kFLeutebi7XeLtTYwmttTxxg2tyUyX0_UF7zj_P-tdq-kZQlud1ENmRaUxLXO5mTFKXD7zPb6BPFNe0ewRQ7Uuv3lDk_IxOf-6i86VDYB8luyesEXq7ra4S4l8akFodW_QYBSZQnUva_CVyzsTNcmgGTyrz2NI6seT1x6Pt1uFdYI97FHKlCCWVL1Z042omfujfta8j8XkTWdhKf3dfsHRWjrw31xqOkgD7uwPKcrC0U-wIj3U0uX0Rz2Tk4T-kIq4XTkKttYpkJqOmMFAYuhk6MDjfRkPWBZhUA + x-amzn-oidc-identity paakayttaja@solita.fi + x-amzn-oidc-data eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZXN0LWtpZCIsImFsZyI6IlJTMjU2IiwiaXNzIjoidGVzdC1pc3MiLCJjbGllbnQiOiJ0ZXN0LWNsaWVudCIsInNpZ25lciI6InRlc3Qtc2lnbmVyIiwiZXhwIjoxODkzNDU2MDAwfQ.eyJzdWIiOiJwYWFrYXl0dGFqYUBzb2xpdGEuZmkiLCJjdXN0b206VklSVFVfbG9jYWxJRCI6InZ2aXJrYW1pZXMiLCJjdXN0b206VklSVFVfbG9jYWxPcmciOiJ0ZXN0aXZpcmFzdG8uZmkiLCJ1c2VybmFtZSI6InRlc3QtdXNlcm5hbWUiLCJleHAiOjE4OTM0NTYwMDAsImlzcyI6InRlc3QtaXNzIn0.BfuDVOFUReiJd6N05Re6affps_47AA0F5o-g6prmXgAnk4lB1S3k9RpovCFU3-R5Zn0p38QTiwi5dENHCHaj1A6MGHHKeYd7vBZK0VquuBxlIQH-4k1MWLvpYnkK3yuEvfmbRb3jYspCA_4N-AF21cCyjd15RiuIawLCEM0Km1DRgLhXIBta6XCGSRwaRmrT7boDRMp7hUkYPpoakCahMC70sjyuvLE0pjAy1_S09g4SkboentI7WhfsfN4uAHbKy6ViVMfsnwVVvKsM8dXav_a-6PoNGywuUbi8nHt8c20KiB_AzAEYSqxbRX1YBd0UHlYS16LbLtMBTOctCBLDMg" + [] + (->> (generate-adds 1) + (map #(merge %1 {:virtu {:localid "vvirkamies" :organisaatio "testivirasto.fi"} + :rooli 2 + })) + insert! + first)) diff --git a/etp-backend/src/test/clj/solita/etp/valvonta_test.clj b/etp-backend/src/test/clj/solita/etp/valvonta_test.clj index b384545ae..465e0a0b9 100644 --- a/etp-backend/src/test/clj/solita/etp/valvonta_test.clj +++ b/etp-backend/src/test/clj/solita/etp/valvonta_test.clj @@ -22,12 +22,28 @@ ; Mimics real handler usage with test assets (handler/handler (merge req {:db ts/*db* :aws-s3-client ts/*aws-s3-client*}))) +(defn- non-nil-key->string [m k] + (if (some? (k m)) + (assoc m k (str (k m))) m)) (def access-token "eyJraWQiOiJ0ZXN0LWtpZCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJwYWFrYXl0dGFqYUBzb2xpdGEuZmkiLCJ0b2tlbl91c2UiOiJhY2Nlc3MiLCJzY29wZSI6Im9wZW5pZCIsImF1dGhfdGltZSI6MTU4MzIzMDk2OSwiaXNzIjoiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3NvbGl0YS9ldHAtY29yZS9mZWF0dXJlL0FFLTQzLWF1dGgtaGVhZGVycy1oYW5kbGluZy9ldHAtYmFja2VuZC9zcmMvbWFpbi9yZXNvdXJjZXMiLCJleHAiOjE4OTM0NTYwMDAsImlhdCI6MTU4MzQxMzQyNCwidmVyc2lvbiI6MiwianRpIjoiNWZkZDdhMjktN2VlYS00ZjNkLWE3YTYtYzIyODQyNmY2MTJiIiwiY2xpZW50X2lkIjoidGVzdC1jbGllbnRfaWQiLCJ1c2VybmFtZSI6InRlc3QtdXNlcm5hbWUifQ.PY5_jWcdxhCyn2EpFpss7Q0R3_xH1PvHi4mxDLorpppHnciGT2kFLeutebi7XeLtTYwmttTxxg2tyUyX0_UF7zj_P-tdq-kZQlud1ENmRaUxLXO5mTFKXD7zPb6BPFNe0ewRQ7Uuv3lDk_IxOf-6i86VDYB8luyesEXq7ra4S4l8akFodW_QYBSZQnUva_CVyzsTNcmgGTyrz2NI6seT1x6Pt1uFdYI97FHKlCCWVL1Z042omfujfta8j8XkTWdhKf3dfsHRWjrw31xqOkgD7uwPKcrC0U-wIj3U0uX0Rz2Tk4T-kIq4XTkKttYpkJqOmMFAYuhk6MDjfRkPWBZhUA") (def oidc-data "eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZXN0LWtpZCIsImFsZyI6IlJTMjU2IiwiaXNzIjoidGVzdC1pc3MiLCJjbGllbnQiOiJ0ZXN0LWNsaWVudCIsInNpZ25lciI6InRlc3Qtc2lnbmVyIiwiZXhwIjoxODkzNDU2MDAwfQ.eyJzdWIiOiJwYWFrYXl0dGFqYUBzb2xpdGEuZmkiLCJjdXN0b206VklSVFVfbG9jYWxJRCI6InZ2aXJrYW1pZXMiLCJjdXN0b206VklSVFVfbG9jYWxPcmciOiJ0ZXN0aXZpcmFzdG8uZmkiLCJ1c2VybmFtZSI6InRlc3QtdXNlcm5hbWUiLCJleHAiOjE4OTM0NTYwMDAsImlzcyI6InRlc3QtaXNzIn0.BfuDVOFUReiJd6N05Re6affps_47AA0F5o-g6prmXgAnk4lB1S3k9RpovCFU3-R5Zn0p38QTiwi5dENHCHaj1A6MGHHKeYd7vBZK0VquuBxlIQH-4k1MWLvpYnkK3yuEvfmbRb3jYspCA_4N-AF21cCyjd15RiuIawLCEM0Km1DRgLhXIBta6XCGSRwaRmrT7boDRMp7hUkYPpoakCahMC70sjyuvLE0pjAy1_S09g4SkboentI7WhfsfN4uAHbKy6ViVMfsnwVVvKsM8dXav_a-6PoNGywuUbi8nHt8c20KiB_AzAEYSqxbRX1YBd0UHlYS16LbLtMBTOctCBLDMg") + +(defn- with-virtu-user [request] + (-> request + (mock/header "x-amzn-oidc-accesstoken" access-token) + (mock/header "x-amzn-oidc-identity" "paakayttaja@solita.fi") + (mock/header "x-amzn-oidc-data" oidc-data))) + +(defn- add-valvonta-and-map-id! [valvonta] + (assoc valvonta :id (valvonta-service/add-valvonta! ts/*db* valvonta))) + +(defn- add-toimenpide-and-map-id! [valvonta-id toimenpide] + (merge toimenpide (valvonta-service/add-toimenpide! ts/*db* ts/*aws-s3-client* {} valvonta-id toimenpide))) + (t/deftest adding-toimenpide (t/testing "Kun uusi toimenpide lisätään, omistajille joilla on Suomi.fi-viestit käytössä lähtee viesti oikealla kuvauksella" (let [suomifi-message-sent (promise) @@ -47,12 +63,7 @@ ) (deliver suomifi-message-sent true))] (with-redefs [suomifi-viestit/send-message! assert-suomifi-message-sent] - (let [kayttaja-id (first (test-kayttajat/insert! - (->> (test-kayttajat/generate-adds 1) - (map #(merge %1 {:virtu {:localid "vvirkamies" :organisaatio "testivirasto.fi"} - :rooli 2 - })) - ))) + (let [kayttaja-id (test-kayttajat/insert-virtu-paakayttaja!) valvonta-id (valvonta-service/add-valvonta! ts/*db* (-> {} (generators/complete valvonta-schema/ValvontaSave) (merge { @@ -70,15 +81,13 @@ }) )) body {:type-id 2 - :deadline-date (.toString (LocalDate/of 2024 11 10)) + :deadline-date (str (LocalDate/of 2024 11 10)) :template-id 2 :description "Tee jotain" } response (handler (-> (mock/request :post (format "/api/private/valvonta/kaytto/%s/toimenpiteet" valvonta-id)) (mock/json-body body) - (mock/header "x-amzn-oidc-accesstoken" access-token) - (mock/header "x-amzn-oidc-identity" "paakayttaja@solita.fi") - (mock/header "x-amzn-oidc-data" oidc-data) + (with-virtu-user) (mock/header "Accept" "application/json"))) response-body (j/read-value (:body response) j/keyword-keys-object-mapper)] @@ -90,12 +99,7 @@ (t/deftest fetching-valvonta (t/testing "Yksittäisen valvonnan hakeminen palauttaa vastauksen") (let [ - kayttaja-id (first (test-kayttajat/insert! - (->> (test-kayttajat/generate-adds 1) - (map #(merge %1 {:virtu {:localid "vvirkamies" :organisaatio "testivirasto.fi"} - :rooli 2 - })) - ))) + kayttaja-id (test-kayttajat/insert-virtu-paakayttaja!) valvonta-id (valvonta-service/add-valvonta! ts/*db* (-> {} (generators/complete valvonta-schema/ValvontaSave) @@ -110,13 +114,11 @@ :havaintopaiva (LocalDate/of 2023 6 1) }))) response (handler (-> (mock/request :get (format "/api/private/valvonta/kaytto/%s" valvonta-id)) - (mock/header "x-amzn-oidc-accesstoken" access-token) - (mock/header "x-amzn-oidc-identity" "paakayttaja@solita.fi") - (mock/header "x-amzn-oidc-data" oidc-data) + (with-virtu-user) (mock/header "Accept" "application/json"))) response-body (j/read-value (:body response) j/keyword-keys-object-mapper) ] - (t/is (:status response) 200) + (t/is (= (:status response) 200)) (t/is (= response-body {:valvoja-id kayttaja-id :katuosoite "katu" :ilmoitustunnus nil @@ -197,15 +199,109 @@ ;;Calling original implementation to ensure the functionality doesn't change (original-html->pdf html-doc output-stream))} (let [new-toimenpide {:type-id 7 - :deadline-date (.toString (LocalDate/of 2023 7 22)) + :deadline-date (str (LocalDate/of 2023 7 22)) :template-id 5 :description "Lähetetään kuulemiskirje, kun myyjä ei ole hankkinut energiatodistusta eikä vastannut kehotukseen tai varoitukseen" :fine 800} response (handler (-> (mock/request :post (format "/api/private/valvonta/kaytto/%s/toimenpiteet" valvonta-id)) (mock/json-body new-toimenpide) - (mock/header "x-amzn-oidc-accesstoken" access-token) - (mock/header "x-amzn-oidc-identity" "paakayttaja@solita.fi") - (mock/header "x-amzn-oidc-data" oidc-data) + (with-virtu-user) (mock/header "Accept" "application/json")))] (t/is (true? @html->pdf-called?)) (t/is (= (:status response) 201))))))) + +(t/deftest adding-and-fetching-valvonta + (let [kayttaja-id (test-kayttajat/insert-virtu-paakayttaja!) + valvonta (-> {} + (generators/complete valvonta-schema/ValvontaSave) + (non-nil-key->string :havaintopaiva) ; Jackson has problems encoding local date + (assoc :ilmoituspaikka-id 1) + (assoc :valvoja-id kayttaja-id))] + (t/testing "Uuden valvonnan luominen" + (let [response (handler (-> (mock/request :post "/api/private/valvonta/kaytto") + (mock/json-body valvonta) + (with-virtu-user) + (mock/header "Accept" "application/json"))) + response-body (j/read-value (:body response) j/keyword-keys-object-mapper)] + (t/is (= (:status response) 201)) + (t/is (= response-body {:id 1})))) + (t/testing "Luotu valvonta on tallennettu ja voidaan hakea" + (let [fetch-response (handler (-> (mock/request :get (format "/api/private/valvonta/kaytto/1")) + (with-virtu-user) + (mock/header "Accept" "application/json"))) + fetched-valvonta (j/read-value (:body fetch-response) j/keyword-keys-object-mapper) + expected-valvonta (assoc valvonta :id 1)] + (t/is (= (:status fetch-response) 200)) + (t/is (= fetched-valvonta expected-valvonta)))))) + +(t/deftest get-toimenpiteet-for-valvonta + (let [kayttaja-id (test-kayttajat/insert-virtu-paakayttaja!) + ;; Create two valvontas + valvonnat (repeatedly 2 #(-> {} + (generators/complete valvonta-schema/ValvontaSave) + (assoc :ilmoituspaikka-id 1 + :valvoja-id kayttaja-id) + add-valvonta-and-map-id!)) + ;; Create 6 toimenpide for each valvonta + toimenpiteet (->> (repeatedly 12 (fn [] (generators/complete {} valvonta-schema/ToimenpideAdd))) + (map vector (flatten (repeatedly (constantly [1 2])))) + (map (fn [[template-id toimenpide]] (assoc toimenpide :template-id template-id))) + (map (fn [toimenpide] (assoc toimenpide :type-id 1))) + (map vector (flatten (repeat (map :id valvonnat)))))] + (doseq [[valvonta-id toimenpide] toimenpiteet] + (add-toimenpide-and-map-id! valvonta-id toimenpide)) + (t/testing "Valvonnalle palautetaan 6 toimenpidettä" + (let [response (handler (-> (mock/request :get (format "/api/private/valvonta/kaytto/%s/toimenpiteet" (-> valvonnat first :id))) + (with-virtu-user) + (mock/header "Accept" "application/json"))) + response-body (j/read-value (:body response) j/keyword-keys-object-mapper)] + (t/is (= (:status response) 200)) + (t/is (= (count response-body) 6)))))) + + +(t/deftest get-valvonnat-with-filters + (let [kayttaja-id (test-kayttajat/insert-virtu-paakayttaja!) + ;; Create two valvontas + valvonnat (repeatedly 2 #(-> {} + (generators/complete valvonta-schema/ValvontaSave) + (assoc :ilmoituspaikka-id 1 + :valvoja-id kayttaja-id) + add-valvonta-and-map-id!)) + ;; Create a toimenpide for each valvonta + toimenpiteet (->> (repeatedly 2 (fn [] (generators/complete {} valvonta-schema/ToimenpideAdd))) + (map (fn [toimenpide] (assoc toimenpide :type-id 1))) + (map vector (flatten (repeatedly (constantly [1 2])))) ; Use two different templates for every other toimenpide + (map (fn [[template-id toimenpide]] (assoc toimenpide :template-id template-id))) + (map vector (flatten (repeat (map :id valvonnat)))) + (mapv #(apply add-toimenpide-and-map-id! %)))] + (t/testing "Hae valvontojen määrä joissa on käytetty asiakirjapohjaa 1" + (let [response (handler (-> (mock/request :get "/api/private/valvonta/kaytto/count") + (mock/query-string {:asiakirjapohja-id 1}) + (with-virtu-user) + (mock/header "Accept" "application/json"))) + response-body (j/read-value (:body response) j/keyword-keys-object-mapper)] + (t/is (= (:status response) 200)) + (t/is (= response-body {:count 1})))) + (t/testing "Hae valvonnat joissa on käytetty asiakirjapohjaa 1" + (let [response (handler (-> (mock/request :get "/api/private/valvonta/kaytto") + (mock/query-string {:asiakirjapohja-id 1}) + (with-virtu-user) + (mock/header "Accept" "application/json"))) + response-body (j/read-value (:body response) j/keyword-keys-object-mapper) + expected-valvonta (-> (first valvonnat) + (assoc :henkilot [] ;Add synthetic fields + :yritykset [] + :energiatodistus nil) + (non-nil-key->string :havaintopaiva)) + expected-last-toimenpide (-> (first toimenpiteet) + (dissoc :description) ; This is not sent here + (assoc :diaarinumero nil) ; Would be generated by asha + (non-nil-key->string :deadline-date)) + received-valvonta (first response-body) + received-last-toimenpide (-> (:last-toimenpide received-valvonta) + (dissoc :publish-time :create-time))] + + (t/is (= (:status response) 200)) + (t/is (= (count response-body) 1)) + (t/is (= (dissoc received-valvonta :last-toimenpide) expected-valvonta)) + (t/is (= received-last-toimenpide expected-last-toimenpide))))))