-
Notifications
You must be signed in to change notification settings - Fork 21
/
test_data.clj
793 lines (753 loc) · 53.4 KB
/
test_data.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
(ns rems.db.test-data
"Populating the database with nice test data."
(:require [clj-time.core :as time]
[rems.context :as context]
[rems.db.applications :as applications]
[rems.db.catalogue :as catalogue]
[rems.db.core :as db]
[rems.db.form :as form]
[rems.db.licenses :as licenses]
[rems.db.resource :as resource]
[rems.db.roles :as roles]
[rems.db.users :as users]
[rems.db.workflow :as workflow]
[rems.db.workflow-actors :as actors]
[rems.locales :as locales]
[ring.util.http-response :refer [bad-request!]])
(:import [java.util UUID]
[org.joda.time DateTimeUtils DateTime]))
(def ^DateTime creation-time (time/now)) ; TODO: no more used, remove?
(def +fake-users+
{:applicant1 "alice"
:applicant2 "malice"
:approver1 "developer"
:approver2 "bob"
:owner "owner"
:reviewer "carl"
:roleless1 "elsa"
:roleless2 "frank"})
(def +fake-user-data+
{"developer" {:eppn "developer" :mail "developer@example.com" :commonName "Developer"}
"alice" {:eppn "alice" :mail "alice@example.com" :commonName "Alice Applicant"}
"malice" {:eppn "malice" :mail "malice@example.com" :commonName "Malice Applicant" :twinOf "alice" :other "Attribute Value"}
"bob" {:eppn "bob" :mail "bob@example.com" :commonName "Bob Approver"}
"carl" {:eppn "carl" :mail "carl@example.com" :commonName "Carl Reviewer"}
"elsa" {:eppn "elsa" :mail "elsa@example.com" :commonName "Elsa Roleless"}
"frank" {:eppn "frank" :mail "frank@example.com" :commonName "Frank Roleless"}
"owner" {:eppn "owner" :mail "owner@example.com" :commonName "Owner"}})
(def +demo-users+
{:applicant1 "RDapplicant1@funet.fi"
:applicant2 "RDapplicant2@funet.fi"
:approver1 "RDapprover1@funet.fi"
:approver2 "RDapprover2@funet.fi"
:owner "RDowner@funet.fi"
:reviewer "RDreview@funet.fi"})
(def +demo-user-data+
{"RDapplicant1@funet.fi" {:eppn "RDapplicant1@funet.fi" :mail "RDapplicant1.test@test_example.org" :commonName "RDapplicant1 REMSDEMO1"}
"RDapplicant2@funet.fi" {:eppn "RDapplicant2@funet.fi" :mail "RDapplicant2.test@test_example.org" :commonName "RDapplicant2 REMSDEMO"}
"RDapprover1@funet.fi" {:eppn "RDapprover1@funet.fi" :mail "RDapprover1.test@rems_example.org" :commonName "RDapprover1 REMSDEMO"}
"RDapprover2@funet.fi" {:eppn "RDapprover2@funet.fi" :mail "RDapprover2.test@rems_example.org" :commonName "RDapprover2 REMSDEMO"}
"RDreview@funet.fi" {:eppn "RDreview@funet.fi" :mail "RDreview.test@rems_example.org" :commonName "RDreview REMSDEMO"}
"RDowner@funet.fi" {:eppn "RDowner@funet.fi" :mail "RDowner.test@test_example.org" :commonName "RDowner REMSDEMO"}})
(defn- create-users-and-roles! []
;; users provided by the fake login
(users/add-user! (+fake-users+ :approver1) (+fake-user-data+ (+fake-users+ :approver1)))
(users/add-user! (+fake-users+ :applicant1) (+fake-user-data+ (+fake-users+ :applicant1)))
(users/add-user! (+fake-users+ :applicant2) (+fake-user-data+ (+fake-users+ :applicant2)))
(users/add-user! (+fake-users+ :approver2) (+fake-user-data+ (+fake-users+ :approver2)))
(users/add-user! (+fake-users+ :reviewer) (+fake-user-data+ (+fake-users+ :reviewer)))
;; users without roles
(users/add-user! (+fake-users+ :roleless1) (+fake-user-data+ (+fake-users+ :roleless1)))
(users/add-user! (+fake-users+ :roleless2) (+fake-user-data+ (+fake-users+ :roleless2)))
;; a user to own things
(users/add-user! (+fake-users+ :owner) (+fake-user-data+ (+fake-users+ :owner)))
(roles/add-role! (+fake-users+ :owner) :owner)
;; invalid user for tests
(db/add-user! {:user "invalid" :userattrs nil}))
(defn- create-demo-users-and-roles! []
;; users used on remsdemo
(doseq [applicant [(+demo-users+ :applicant1) (+demo-users+ :applicant2)]]
(users/add-user! applicant (+demo-user-data+ applicant)))
(doseq [approver [(+demo-users+ :approver1) (+demo-users+ :approver2)]]
(users/add-user! approver (+demo-user-data+ approver)))
(let [reviewer (+demo-users+ :reviewer)]
(users/add-user! reviewer (+demo-user-data+ reviewer)))
;; a user to own things
(let [owner (+demo-users+ :owner)]
(users/add-user! owner (+demo-user-data+ owner))
(roles/add-role! owner :owner)))
(defn- create-expired-form! []
(let [yesterday (time/minus (time/now) (time/days 1))]
;; only used from create-test-data!
(db/create-form! {:organization "nbn" :title "Expired form, should not be seen by applicants" :user (+fake-users+ :owner) :end yesterday})))
(defn- create-expired-license! []
(let [owner (+fake-users+ :owner) ; only used from create-test-data!
yesterday (time/minus (time/now) (time/days 1))]
(db/create-license! {:modifieruserid owner :owneruserid owner :title "expired license" :type "link" :textcontent "http://expired" :end yesterday})))
(defn- create-basic-form!
"Creates a bilingual form with all supported field types. Returns id of the form meta."
[users]
(:id (form/create-form!
(users :owner)
{:organization "nbn"
:title "Basic form"
:items [;; all form item types
{:title {:en "Project name"
:fi "Projektin nimi"}
:optional false
:type "description"
:input-prompt {:en "Project"
:fi "Projekti"}}
{:title {:en "Purpose of the project"
:fi "Projektin tarkoitus"}
:optional false
:type "texta"
:input-prompt {:en "The purpose of the project is to..."
:fi "Projektin tarkoitus on..."}}
{:title {:en "Start date of the project"
:fi "Projektin aloituspäivä"}
:optional true
:type "date"}
{:title {:en "Project plan"
:fi "Projektisuunnitelma"}
:optional true
:type "attachment"}
{:title {:en "Project team size"
:fi "Projektitiimin koko"}
:optional true
:type "option"
:options [{:key "1-5"
:label {:en "1-5 persons"
:fi "1-5 henkilöä"}}
{:key "6-20"
:label {:en "6-20 persons"
:fi "6-20 henkilöä"}}
{:key "20+"
:label {:en "over 20 persons"
:fi "yli 20 henkilöä"}}]}
{:title {:en "Where will the data be used?"
:fi "Missä dataa tullaan käyttämään?"}
:optional true
:type "multiselect"
:options [{:key "EU"
:label {:en "Inside EU"
:fi "EU:n sisällä"}}
{:key "USA"
:label {:en "Inside USA"
:fi "Yhdysvalloissa"}}
{:key "Other"
:label {:en "Elsewhere"
:fi "Muualla"}}]}
;; fields which support maxlength
{:title {:en "Project acronym"
:fi "Projektin lyhenne"}
:optional true
:type "text"
:maxlength 10}
{:title {:en "Research plan"
:fi "Tutkimussuunnitelma"}
:optional true
:type "texta"
:maxlength 100}]})))
(defn create-thl-demo-form!
[users]
(:id (form/create-form!
(users :owner)
{:organization "nbn"
:title "THL form"
:items [{:title {:en "Application title"
:fi "Hakemuksen otsikko"}
:optional true
:type "description"
:input-prompt {:en "Study of.."
:fi "Tutkimus aiheesta.."}}
{:title {:en "1. Research project full title"
:fi "1. Tutkimusprojektin täysi nimi"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "2. This is an amendment of a previous approved application"
:fi "2. Hakemus täydentää edellistä hakemusta"}
:optional false
:type "option"
:options [{:key false
:label {:en "no"
:fi "ei"}}
{:key true
:label {:en "yes"
:fi "kyllä"}}]}
{:title {:en "If yes, what were the previous project permit code/s?"
:fi "Jos kyllä, mitkä olivat edelliset projektin lupakoodit?"}
:optional true
:type "text"}
{:title {:en "3. Study PIs (name, titile, affiliation, email)"
:fi "3. Henkilöstö (nimi, titteli, yhteys projektiin, sähköposti)"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "4. Contact person for application if different than applicant (name, email)"
:fi "4. Yhteyshenkilö, jos ei sama kuin hakija (nimi, sähköposti)"}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "5. Research project start date"
:fi "5. Projektin aloituspäivä"}
:optional false
:type "date"}
{:title {:en "6. Research project end date"
:fi "6. Projektin lopetuspäivä"}
:optional false
:type "date"}
{:title {:en "7. Describe in detail the aims of the study and analysis plan"
:fi "7. Kuvaile yksityiskohtaisesti tutkimussuunnitelma"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "8. If this is an amendment, please describe briefly what is new"
:fi "8. Jos tämä on täydennys edelliseen hakemukseen, kuvaile tiiviisti, mikä on muuttunut."}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "9. Public description of the project (in Finnish, when possible), to be published in THL Biobank."
:fi "9. Kuvaile yksityiskohtaisesti tutkimussuunnitelma"}
:input-prompt {:en "Meant for sample donors and for anyone interested in the research done using THL Biobank's sample collections. This summary and the name of the Study PI will be published in THL Biobank's web pages."
:fi "Tarkoitettu aineistojen lahjoittajille ja kaikille, joita kiinnostaa THL:n Biopankkia käyttävät tutkimusprojektit. Tämä kuvaus sekä tutkijan nimi julkaistaan THL:n nettisivuilla, kun sopimus on allekirjoitettu."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "10. Place/plces of research, including place of sample and/or data analysis."
:fi "10. Tutkimuksen yysinen sijainti, mukaanlukien paikka, missä data-analyysi toteutetaan."}
:input-prompt {:en "List all research center involved in this study, and each center's role. Specify which centers will analyze which data and/or samples.."
:fi "Listaa kaikki tutkimuskeskukset, jotka osallistuvat tähän tutkimukseen, ml. niiden roolit tutkimuksessa. Erittele, missä analysoidaan mikäkin näyte."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "11. Description of other research group members and their role in the applied project."
:fi "11. Kuvaus muista tutkimukseen osallistuvista henkilöistä, ja heidän roolistaan projektissa."}
:input-prompt {:en "For every group member: name, title, affiliation, contact information. In addition describe earch member's role in the project (e.g. cohor representative, data analyst, etc.)"
:fi "Anna jokaisesta jäsenestä: nimi, titteli, yhteys projektiin, yhteystiedot. Kuvaile lisäki jokaisen henkilön rooli projektissa."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "12. Specify selection criteria of study participants (if applicable)"
:fi "12. Erottele tukimuksen osallistujien valintakriteerit (jos käytetty)"}
:input-prompt {:en "Describe any specific criteria by which study participans will be selected. For example, selection for specific age group, gender, area/locality, disease status etc."
:fi "Kuvaa tarkat valintakriteerit, joilla tutkimuksen osallistujat valitaan. Esimerkiksi ikäryhmä, sukupuoli, alue, taudin tila jne."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "13. Specify requested phenotype data (information on variables is found at https://kite.fimm.fi)"
:fi "13. Tarkenna pyydetty fenotyyppidatta (tietoa muuttujista on saatavilla osoitteesta https://kite.fimm.fi)"}
:input-prompt {:en "Desrcibe in detail the phenotype data needed for the study. Lists of variables are to be attached to the application (below)."
:fi "Kuvaile yksityiskohtaisesti tutkimukseen tarvittava fenotyyppidata. Lista muuttujista lisätään hakemukseen liitteenä."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "14. Specify requested genomics or other omics data (if applicable)"
:fi "14. Kuvaile tarvittava genomiikkadata."}
:input-prompt {:en "Specify in detail the requested data format for different genomics or other omics data types. Information of available omics data is found at THL Biobank web page (www.thl.fi/biobank/researchers)"
:fi "Kuvaile tarvitsemasi genomiikkadata. Lisätietoa saatavilla osoitteesta www.thl.fi/biobank/researchers"}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "16. Are biological samples requested?"
:fi "16. Pyydetäänkö biologisia näytteitä?"}
:optional false
:type "option"
:options [{:key false
:label {:en "no"
:fi "ei"}}
{:key true
:label {:en "yes"
:fi "kyllä"}}]}
{:title {:en "The type and amount of biological samples requested"
:fi "Biologisten näytteiden tyypit ja määrät."}
:input-prompt {:en "Type and amount of samples and any additional specific criteria."
:fi "Biologisten näytteiden määrät, tyypit, ja mahdolliset muut kriteerit."}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "17. What study results will be returned to THL Biobank (if any)?"
:fi "17. Mitä tutkimustuloksia tullaan palauttamaan THL Biopankkiin?"}
:input-prompt {:en "Study results such as new laboratory measurements, produced omics data and other analysis data (\"raw data\")"
:fi "Tutkimustuloksia kuten mittaustuloksia, uutta biologista dataa, tai muita analyysien tuloksia (\"raaka-dataa\")"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "Expected date for return of study results"
:fi "Odotettu tutkimustuloksien palautuspäivämäärä"}
:optional true
:type "date"}
{:title {:en "18. Ethical aspects of the project"
:fi "18. Tutkimuksen eettiset puolet"}
:input-prompt {:en "If you have any documents from an ethical board, please provide them as an attachment."
:fi "Liitä mahdolliset eettisen toimikunnan lausunnot hakemuksen loppuun."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "19. Project keywords (max 5)"
:fi "19. Projektin avainsanat (maks. 5)"}
:input-prompt {:en "List a few keywords that are related to this research project (please separate with comma)"
:fi "Listaa muutama projektiin liittyvä avainsana, pilkuilla erotettuina."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "20. Planned publications (max 3)"
:fi "20. Suunnitellut julkaisut (maks. 3)"}
:input-prompt {:en "Planned publication titles / research topics"
:fi "Suunniteltujen julkaisujen otsikot / tutkimusaiheet"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "21. Funding information"
:fi "21. Rahoitus"}
:input-prompt {:en "List all funding sources which will be used for this research project."
:fi "Listaa kaikki rahoituslähteet joita tullaan käyttämään tähän tutkimusprojektiin"}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "22. Invoice address (Service prices: www.thl.fi/biobank/researchers)"
:fi "22. Laskutusosoite (Palveluhinnasto: www.thl.fi/biobank/researchers)"}
:input-prompt {:en "Electronic invoice address when possible + invoicing reference"
:fi "Sähköinen laskutus, kun mahdollista. Lisäksi viitenumero."}
:optional false
:type "texta"
:maxlength 100}
{:title {:en "23. Other information"
:fi "23. Muuta"}
:input-prompt {:en "Any other relevant information for the application"
:fi "Muuta hakemukseen liittyvää oleellista tietoa"}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "THL Biobank's registered area/s of operation to which the research project complies:"
:fi "THL Biobankin toimialueet, joihin tutkimusprojekti liittyy:"}
:optional false
:type "multiselect"
:options [{:key "population_health"
:label {:en "Promoting the population's health"
:fi "Edistää kansanterveytttä"}}
{:key "disease_mechanisms"
:label {:en "Identifying factors involved in disease mechanisms"
:fi "Tunnistaa tautien mekanismeja"}}
{:key "disease_prevention"
:label {:en "Disease prevention"
:fi "Estää tautien leviämistä"}}
{:key "health_product_development"
:label {:en "Developing products that promote the welfare and health of the population"
:fi "Kehittää tuotteita, jotka edistävät kansanterveyttä."}}
{:key "treatment_development"
:label {:en "Developing products and treatments for diseases"
:fi "Kehittää tuotteita ja parannuskeinoja tautien varalle"}}
{:key "other"
:label {:en "Other"
:fi "Muuta"}}]}
{:title {:en "Other, specify"
:fi "Muuta, tarkenna"}
:optional true
:type "texta"
:maxlength 100}
{:title {:en "Data management plan (pdf)"
:fi "Datanhallintasuunnitelma (pdf)"}
:optional true
:type "attachment"}]})))
(defn- create-workflows! [users]
(let [approver1 (users :approver1)
approver2 (users :approver2)
reviewer (users :reviewer)
owner (users :owner)
minimal (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "minimal" :fnlround 0}))
simple (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "simple" :fnlround 0}))
with-review (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "with review" :fnlround 1}))
two-round (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "two rounds" :fnlround 1}))
different (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "two rounds, different approvers" :fnlround 1}))
expired (:id (db/create-workflow! {:organization "nbn" :owneruserid owner :modifieruserid owner :title "workflow has already expired, should not be seen" :fnlround 0 :end (time/minus (time/now) (time/years 1))}))
dynamic (:id (workflow/create-workflow! {:user-id owner
:organization "nbn"
:title "dynamic workflow"
:type :dynamic
:handlers [approver1]}))]
;; either approver1 or approver2 can approve
(actors/add-approver! simple approver1 0)
(actors/add-approver! simple approver2 0)
;; first reviewer reviews, then approver1 can approve
(actors/add-reviewer! with-review reviewer 0)
(actors/add-approver! with-review approver1 1)
;; only approver1 can approve
(actors/add-approver! two-round approver1 0)
(actors/add-approver! two-round approver1 1)
;; first approver2, then approver1
(actors/add-approver! different approver2 0)
(actors/add-approver! different approver1 1)
;; attach both kinds of licenses to all workflows
(let [link (:id (db/create-license!
{:modifieruserid owner :owneruserid owner :title "non-localized link license"
:type "link" :textcontent "http://invalid"}))
text (:id (db/create-license!
{:modifieruserid owner :owneruserid owner :title "non-localized text license"
:type "text" :textcontent "non-localized content"}))]
(db/create-license-localization!
{:licid link :langcode "en" :title "CC Attribution 4.0"
:textcontent "https://creativecommons.org/licenses/by/4.0/legalcode"})
(db/create-license-localization!
{:licid link :langcode "fi" :title "CC Nimeä 4.0"
:textcontent "https://creativecommons.org/licenses/by/4.0/legalcode.fi"})
(db/create-license-localization!
{:licid text :langcode "fi" :title "Yleiset käyttöehdot"
:textcontent (apply str (repeat 10 "Suomenkielinen lisenssiteksti. "))})
(db/create-license-localization!
{:licid text :langcode "en" :title "General Terms of Use"
:textcontent (apply str (repeat 10 "License text in English. "))})
(doseq [wfid [minimal simple with-review two-round different dynamic]]
(db/create-workflow-license! {:wfid wfid :licid link :round 0})
(db/create-workflow-license! {:wfid wfid :licid text :round 0})
(db/set-workflow-license-validity! {:licid link :start (time/minus (time/now) (time/years 1)) :end nil})
(db/set-workflow-license-validity! {:licid text :start (time/minus (time/now) (time/years 1)) :end nil})))
{:minimal minimal
:simple simple
:with-review with-review
:dynamic-with-review dynamic
:two-round two-round
:different different
:expired expired
:dynamic dynamic}))
(defn- create-resource-license! [resid text owner]
(let [licid (:id (db/create-license!
{:modifieruserid owner :owneruserid owner :title "resource license"
:type "link" :textcontent "http://invalid"}))]
(db/create-license-localization!
{:licid licid :langcode "en" :title (str text " (en)")
:textcontent "https://www.apache.org/licenses/LICENSE-2.0"})
(db/create-license-localization!
{:licid licid :langcode "fi" :title (str text " (fi)")
:textcontent "https://www.apache.org/licenses/LICENSE-2.0"})
(db/create-resource-license! {:resid resid :licid licid})
(db/set-resource-license-validity! {:licid licid :start (time/minus (time/now) (time/years 1)) :end nil})
licid))
(defn- create-catalogue-item! [resource workflow form localizations]
(let [id (:id (db/create-catalogue-item!
{:title "non-localized title" :resid resource :wfid workflow :form form}))]
(doseq [[lang title] localizations]
(catalogue/create-catalogue-item-localization! {:id id :langcode lang :title title}))
id))
(defn trim-value-if-longer-than-fields-maxlength [value maxlength]
(if (and maxlength (> (count value) maxlength))
(subs value 0 maxlength)
value))
(defn- create-draft! [user-id catids wfid field-value & [now]]
(let [app-id (applications/create-new-draft-at-time user-id wfid (or now (time/now)))
catids (if (vector? catids) catids [catids])
_ (doseq [catid catids]
(db/add-application-item! {:application app-id :item catid}))
form (binding [context/*lang* :en]
(applications/get-form-for user-id app-id))
dynamic-workflow? (= :workflow/dynamic (get-in form [:application :workflow :type]))
save-draft-command (atom {:type :application.command/save-draft
:actor user-id
:application-id app-id
:time (get-in form [:application :start])
:field-values []})]
(when dynamic-workflow?
(applications/add-application-created-event! {:application-id app-id
:catalogue-item-ids catids
:time (get-in form [:application :start])
:actor user-id}))
(doseq [{item-id :id maxlength :maxlength} (:items form)
:let [trimmed-value (trim-value-if-longer-than-fields-maxlength field-value maxlength)]]
(db/save-field-value! {:application app-id :form (:id form)
:item item-id :user user-id :value trimmed-value})
(swap! save-draft-command
update :field-values
conj {:field item-id :value trimmed-value}))
(db/update-application-description! {:id app-id :description field-value})
(when-not dynamic-workflow?
(doseq [{license-id :id} (:licenses form)]
(db/save-license-approval! {:catappid app-id
:round 0
:licid license-id
:actoruserid user-id
:state "approved"})))
(when dynamic-workflow?
(let [error (applications/command! {:type :application.command/accept-licenses
:actor user-id
:application-id app-id
:accepted-licenses (map :id (:licenses form))
:time (time/now)})]
(assert (nil? error) error))
(let [error (applications/command! @save-draft-command)]
(assert (nil? error) error)))
app-id))
(defn- create-applications! [catid wfid applicant approver]
(binding [context/*tempura* (locales/tempura-config)]
(create-draft! applicant catid wfid "draft application")
(let [application (create-draft! applicant catid wfid "applied application")]
(applications/submit-application applicant application))
(let [application (create-draft! applicant catid wfid "rejected application")]
(applications/submit-application applicant application)
(applications/reject-application approver application 0 "comment for rejection"))
(let [application (create-draft! applicant catid wfid "accepted application")]
(applications/submit-application applicant application)
(applications/approve-application approver application 0 "comment for approval"))
(let [application (create-draft! applicant catid wfid "returned application")]
(applications/submit-application applicant application)
(applications/return-application approver application 0 "comment for return"))))
(defn- run-and-check-dynamic-command! [& args]
(let [result (apply applications/command! args)]
(assert (nil? result) {:actual result})
result))
(defn- create-disabled-applications! [catid wfid applicant approver]
(binding [context/*tempura* (locales/tempura-config)]
(create-draft! applicant catid wfid "draft with disabled item")
(let [appid1 (create-draft! applicant catid wfid "approved application with disabled item")]
(run-and-check-dynamic-command! {:application-id appid1
:actor applicant
:time (time/now)
:type :application.command/submit}))
(let [appid2 (create-draft! applicant catid wfid "submitted application with disabled item")]
(run-and-check-dynamic-command! {:application-id appid2
:actor applicant
:time (time/now)
:type :application.command/submit})
(run-and-check-dynamic-command! {:application-id appid2
:actor applicant
:time (time/now)
:type :application.command/approve
:comment "Looking good"}))))
(defn- create-bundled-application! [catid catid2 wfid applicant approver]
(binding [context/*tempura* (locales/tempura-config)]
(let [app-id (create-draft! applicant [catid catid2] wfid "bundled application")]
(applications/submit-application applicant app-id)
(applications/return-application approver app-id 0 "comment for return")
(applications/submit-application applicant app-id))))
(defn- create-member-applications! [catid wfid applicant approver members]
(let [appid1 (create-draft! applicant catid wfid "draft with invited members")]
(run-and-check-dynamic-command! {:application-id appid1
:actor applicant
:time (time/now)
:type :application.command/invite-member
:member {:name "John Smith" :email "john.smith@example.org"}}))
(let [appid2 (create-draft! applicant catid wfid "submitted with members")]
(run-and-check-dynamic-command! {:application-id appid2
:actor applicant
:time (time/now)
:type :application.command/invite-member
:member {:name "John Smith" :email "john.smith@example.org"}})
(run-and-check-dynamic-command! {:application-id appid2
:actor applicant
:time (time/now)
:type :application.command/submit})
(doseq [member members]
(run-and-check-dynamic-command! {:application-id appid2
:actor approver
:time (time/now)
:type :application.command/add-member
:member member}))))
(defn- create-dynamic-applications! [catid wfid users]
(let [applicant (users :applicant1)
approver (users :approver1)
reviewer (users :reviewer)]
(let [app-id (create-draft! applicant [catid] wfid "dynamic application")]
(run-and-check-dynamic-command! {:application-id app-id :actor applicant :time (time/now) :type :application.command/submit}))
(let [app-id (create-draft! applicant catid wfid "application with comment")] ; approved with comment
(run-and-check-dynamic-command! {:application-id app-id :actor applicant :time (time/now) :type :application.command/submit}) ; submit
(run-and-check-dynamic-command! {:application-id app-id :actor approver :time (time/now) :type :application.command/request-comment :commenters [reviewer] :comment "please have a look"})
(run-and-check-dynamic-command! {:application-id app-id :actor reviewer :time (time/now) :type :application.command/comment :comment "looking good"})
(run-and-check-dynamic-command! {:application-id app-id :actor approver :time (time/now) :type :application.command/approve :comment "Thank you! Approved!"}))
(let [app-id (create-draft! applicant catid wfid "application in commenting")] ; still in commenting
(run-and-check-dynamic-command! {:application-id app-id :actor applicant :time (time/now) :type :application.command/submit})
(run-and-check-dynamic-command! {:application-id app-id :actor approver :time (time/now) :type :application.command/request-comment :commenters [reviewer] :comment ""}))
(let [app-id (create-draft! applicant catid wfid "application in deciding")] ; still in deciding
(run-and-check-dynamic-command! {:application-id app-id :actor applicant :time (time/now) :type :application.command/submit})
(run-and-check-dynamic-command! {:application-id app-id :actor approver :time (time/now) :type :application.command/request-decision :deciders [reviewer] :comment ""}))))
(defn- create-review-applications! [catid wfid users]
(let [applicant (users :applicant1)
approver (users :approver1)
reviewer (users :reviewer)]
(binding [context/*tempura* (locales/tempura-config)]
(let [app-id (create-draft! applicant catid wfid "application with review")]
(applications/submit-application applicant app-id)
(applications/review-application reviewer app-id 0 "comment for review")
(applications/approve-application approver app-id 1 "comment for approval")) ; already reviewed and approved
(let [app-id (create-draft! applicant catid wfid "application in review")]
(applications/submit-application applicant app-id))))) ; still in review
(defn- create-application-with-expired-resource-license! [wfid form users]
(let [applicant (users :applicant1)
owner (users :owner)
resource-id (:id (db/create-resource! {:resid "Resource that has expired license" :organization "nbn" :owneruserid owner :modifieruserid owner}))
year-ago (time/minus (time/now) (time/years 1))
yesterday (time/minus (time/now) (time/days 1))
licid-expired (create-resource-license! resource-id "License that has expired" owner)
_ (db/set-resource-license-validity! {:licid licid-expired :start year-ago :end yesterday})
item-with-expired-license (create-catalogue-item! resource-id wfid form {"en" "Resource with expired resource license"
"fi" "Resurssi jolla on vanhentunut resurssilisenssi"})]
(binding [context/*tempura* (locales/tempura-config)]
(let [application (create-draft! applicant item-with-expired-license wfid "applied when license was valid that has since expired" (time/minus (time/now) (time/days 2)))]
(applications/submit-application applicant application)))))
(defn- create-application-before-new-resource-license! [wfid form users]
(let [applicant (users :applicant1)
owner (users :owner)
resource-id (:id (db/create-resource! {:resid "Resource that has a new resource license" :organization "nbn" :owneruserid owner :modifieruserid owner}))
licid-new (create-resource-license! resource-id "License that was just created" owner)
_ (db/set-resource-license-validity! {:licid licid-new :start (time/now) :end nil})
item-without-new-license (create-catalogue-item! resource-id wfid form {"en" "Resource with just created new resource license"
"fi" "Resurssi jolla on uusi resurssilisenssi"})]
(binding [context/*tempura* (locales/tempura-config)]
(let [application (create-draft! applicant item-without-new-license wfid "applied before license was valid" (time/minus (time/now) (time/days 2)))]
(applications/submit-application applicant application)))))
(defn create-performance-test-data! []
(let [resource-count 1000
application-count 1000
user-count 1000
handlers [(+fake-users+ :approver1)
(+fake-users+ :approver2)]
owner (+fake-users+ :owner)
workflow-id (:id (workflow/create-workflow! {:user-id owner
:organization "perf"
:title "Performance tests"
:type :dynamic
:handlers handlers}))
form-id (:id (form/create-form!
owner
{:organization "perf"
:title "Performance tests"
:items [{:title {:en "Project name"
:fi "Projektin nimi"}
:optional false
:type "description"
:input-prompt {:en "Project"
:fi "Projekti"}}
{:title {:en "Project description"
:fi "Projektin kuvaus"}
:optional false
:type "texta"
:input-prompt {:en "The purpose of the project is to..."
:fi "Projektin tarkoitus on..."}}]}))
form (form/get-form form-id)
license-id (:id (licenses/create-license!
{:licensetype "text"
:title "Performance License"
:textcontent "Be fast."
:localizations {:en {:title "Performance license"
:textcontent "Be fast."}
:fi {:title "Suorituskykylisenssi"
:textcontent "Ole nopea."}}}
owner))
cat-item-ids (vec (for [_ (range resource-count)]
(let [uuid (UUID/randomUUID)
resource (resource/create-resource!
{:resid (str "urn:uuid:" uuid)
:organization "perf"
:licenses [license-id]}
owner)
_ (assert (:success resource))
cat-item (catalogue/create-catalogue-item! {:title (str "Performance test resource " uuid)
:form form-id
:resid (:id resource)
:wfid workflow-id})]
(:id cat-item))))
user-ids (vec (for [n (map inc (range user-count))]
(let [user-id (str "perftester" n)]
(users/add-user! user-id {:eppn user-id
:mail (str user-id "@example.com")
:commonName (str "Performance Tester " n)})
user-id)))]
(doseq [_ (range application-count)]
(let [cat-item-id (rand-nth cat-item-ids)
user-id (rand-nth user-ids)
handler (rand-nth handlers)
app-id (:application-id (applications/create-application! user-id [cat-item-id]))]
(assert (nil? (applications/command!
{:type :application.command/save-draft
:actor user-id
:time (time/now)
:application-id app-id
:field-values [{:field (:id (first (:fields form)))
:value (str "Performance test application " (UUID/randomUUID))}
{:field (:id (second (:fields form)))
;; 5000 bytes of lorem ipsum
:value "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut non diam vel erat dapibus facilisis vel vitae nunc. Curabitur at fermentum lorem. Cras et bibendum ante. Etiam convallis erat justo. Phasellus cursus molestie vehicula. Etiam molestie tellus vitae consectetur dignissim. Pellentesque euismod hendrerit mi sed tincidunt. Integer quis lorem ut ipsum egestas hendrerit. Aenean est nunc, mattis euismod erat in, sodales rutrum mauris. Praesent sit amet risus quis felis congue ultricies. Nulla facilisi. Sed mollis justo id tristique volutpat.\n\nPhasellus augue mi, facilisis ac velit et, pharetra tristique nunc. Pellentesque eget arcu quam. Curabitur dictum nulla varius hendrerit varius. Proin vulputate, ex lacinia commodo varius, ipsum velit viverra est, eget molestie dui nisi non eros. Nulla lobortis odio a magna mollis placerat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer consectetur libero ut gravida ullamcorper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec aliquam feugiat mollis. Quisque massa lacus, efficitur vel justo vel, elementum mollis magna. Maecenas at sem sem. Praesent sed ex mattis, egestas dui non, volutpat lorem. Nulla tempor, nisi rutrum accumsan varius, tellus elit faucibus nulla, vel mattis lacus justo at ante. Sed ut mollis ex, sed tincidunt ex.\n\nMauris laoreet nibh eget erat tincidunt pharetra. Aenean sagittis maximus consectetur. Curabitur interdum nibh sed tincidunt finibus. Sed blandit nec lorem at iaculis. Morbi non augue nec tortor hendrerit mollis ut non arcu. Suspendisse maximus nec ligula a efficitur. Etiam ultrices rhoncus leo quis dapibus. Integer vel rhoncus est. Integer blandit varius auctor. Vestibulum suscipit suscipit risus, sit amet venenatis lacus iaculis a. Duis eu turpis sit amet nibh sagittis convallis at quis ligula. Sed eget justo quis risus iaculis lacinia vitae a justo. In hac habitasse platea dictumst. Maecenas euismod et lorem vel viverra.\n\nDonec bibendum nec ipsum in volutpat. Vivamus in elit venenatis, venenatis libero ac, ultrices dolor. Morbi quis odio in neque consequat rutrum. Suspendisse quis sapien id sapien fermentum dignissim. Nam eu est vel risus volutpat mollis sed quis eros. Proin leo nulla, dictum id hendrerit vitae, scelerisque in elit. Proin consectetur sodales arcu ac tristique. Suspendisse ut elementum ligula, at rhoncus mauris. Aliquam lacinia at diam eget mattis. Phasellus quam leo, hendrerit sit amet mi eget, porttitor aliquet velit. Proin turpis ante, consequat in enim nec, tempus consequat magna. Vestibulum fringilla ac turpis nec malesuada. Proin id lectus iaculis, suscipit erat at, volutpat turpis. In quis faucibus elit, ut maximus nibh. Sed egestas egestas dolor.\n\nNulla varius orci quam, id auctor enim ultrices nec. Morbi et tellus ac metus sodales convallis sed vehicula neque. Pellentesque rhoncus mattis massa a bibendum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce tincidunt nulla non aliquet facilisis. Praesent nisl nisi, finibus id odio sed, consectetur feugiat mauris. Suspendisse sed lacinia ligula. Duis vitae nisl leo. Donec erat arcu, feugiat sit amet sagittis ac, scelerisque nec est. Pellentesque finibus mauris nulla, in maximus sapien pharetra vitae. Sed leo elit, consequat eu aliquam vitae, feugiat ut eros. Pellentesque dictum feugiat odio sed commodo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin neque quam, varius vel libero sit amet, rhoncus sollicitudin ex. In a dui non neque malesuada pellentesque.\n\nProin tincidunt nisl non commodo faucibus. Sed porttitor arcu neque, vitae bibendum sapien placerat nec. Integer eget tristique orci. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec eu molestie eros. Nunc iaculis rhoncus enim, vel mattis felis fringilla condimentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean ac augue nulla. Phasellus vitae nulla lobortis, mattis magna ac, gravida ipsum. Aenean ornare non nunc non luctus. Aenean lacinia lectus nec velit finibus egestas vel ut ipsum. Cras hendrerit rhoncus erat, vel maximus nunc.\n\nPraesent quis imperdiet quam. Praesent ligula tellus, consectetur sed lacus eu, malesuada condimentum tellus. Donec et diam hendrerit, dictum diam quis, aliquet purus. Suspendisse pulvinar neque at efficitur iaculis. Nulla erat orci, euismod id velit sed, dictum hendrerit arcu. Nulla aliquam molestie aliquam. Duis et semper nisi, eget commodo arcu. Praesent rhoncus, nulla id sodales eleifend, ante ipsum pellentesque augue, id iaculis sem est vitae est. Phasellus cursus diam a lorem vestibulum sodales. Nullam lacinia tortor vel tellus commodo, sit amet sodales quam malesuada.\n\nNulla tempor lectus vel arcu feugiat, vel dapibus ex dapibus. Maecenas purus justo, aliquet et sem sit amet, tincidunt venenatis dui. Nulla eget purus id sapien elementum rutrum eu vel libero. Cras non accumsan justo posuere."}]})))
(assert (nil? (applications/command!
{:type :application.command/submit
:actor user-id
:time (time/now)
:application-id app-id})))
(assert (nil? (applications/command!
{:type :application.command/approve
:actor handler
:time (time/now)
:application-id app-id
:comment "Looks fine."})))))))
(defn create-test-data! []
(DateTimeUtils/setCurrentMillisFixed (.getMillis creation-time))
(try
(db/add-api-key! {:apikey 42 :comment "test data"})
(create-users-and-roles!)
(let [res1 (:id (db/create-resource! {:resid "urn:nbn:fi:lb-201403262" :organization "nbn" :owneruserid (+fake-users+ :owner) :modifieruserid (+fake-users+ :owner)}))
res2 (:id (db/create-resource! {:resid "Extra Data" :organization "nbn" :owneruserid (+fake-users+ :owner) :modifieruserid (+fake-users+ :owner)}))
_ (:id (db/create-resource! {:resid "Expired Resource, should not be seen" :organization "nbn" :owneruserid (+fake-users+ :owner) :modifieruserid (+fake-users+ :owner) :end (time/minus (time/now) (time/years 1))}))
form (create-basic-form! +fake-users+)
_ (create-expired-form!)
workflows (create-workflows! +fake-users+)
_ (create-catalogue-item! res1 (:minimal workflows) form
{"en" "ELFA Corpus, direct approval"
"fi" "ELFA-korpus, suora hyväksyntä"})
simple (create-catalogue-item! res1 (:simple workflows) form
{"en" "ELFA Corpus, one approval"
"fi" "ELFA-korpus, yksi hyväksyntä"})
bundlable (create-catalogue-item! res2 (:simple workflows) form
{"en" "ELFA Corpus, one approval (extra data)"
"fi" "ELFA-korpus, yksi hyväksyntä (lisäpaketti)"})
with-review (create-catalogue-item! res1 (:with-review workflows) form
{"en" "ELFA Corpus, with review"
"fi" "ELFA-korpus, katselmoinnilla"})
_ (create-catalogue-item! res1 (:different workflows) form
{"en" "ELFA Corpus, two rounds of approval by different approvers"
"fi" "ELFA-korpus, kaksi hyväksyntäkierrosta eri hyväksyjillä"})
disabled (create-catalogue-item! res1 (:simple workflows) form
{"en" "ELFA Corpus, one approval (extra data, disabled)"
"fi" "ELFA-korpus, yksi hyväksyntä (lisäpaketti, pois käytöstä)"})]
(create-resource-license! res2 "Some test license" (+fake-users+ :owner))
(db/set-catalogue-item-state! {:id disabled :enabled false})
(create-applications! simple (:simple workflows) (+fake-users+ :approver1) (+fake-users+ :approver1))
(create-bundled-application! simple bundlable (:simple workflows) (+fake-users+ :applicant1) (+fake-users+ :approver1))
(create-review-applications! with-review (:with-review workflows) +fake-users+)
(create-application-with-expired-resource-license! (:simple workflows) form +fake-users+)
(create-application-before-new-resource-license! (:simple workflows) form +fake-users+)
(create-expired-license!)
(let [dynamic (create-catalogue-item! res1 (:dynamic workflows) form
{"en" "Dynamic workflow" "fi" "Dynaaminen työvuo"})]
(create-dynamic-applications! dynamic (:dynamic workflows) +fake-users+))
(let [thlform (create-thl-demo-form! +fake-users+)
thl-catid (create-catalogue-item! res1 (:dynamic workflows) thlform {"en" "THL catalogue item" "fi" "THL katalogi-itemi"})]
(create-member-applications! thl-catid (:dynamic workflows) (+fake-users+ :applicant1) (+fake-users+ :approver1) [{:userid (+fake-users+ :applicant2)}]))
(let [dynamic-disabled (create-catalogue-item! res1 (:dynamic workflows) form
{"en" "Dynamic workflow (disabled)"
"fi" "Dynaaminen työvuo (pois käytöstä)"})]
(create-disabled-applications! dynamic-disabled (:dynamic workflows) (+fake-users+ :approver1) (+fake-users+ :approver1))
(db/set-catalogue-item-state! {:id dynamic-disabled :enabled false}))
(let [dynamic-expired (create-catalogue-item! res1 (:dynamic workflows) form
{"en" "Dynamic workflow (expired)"
"fi" "Dynaaminen työvuo (vanhentunut)"})]
(db/set-catalogue-item-state! {:id dynamic-expired :end (time/now)})))
(finally
(DateTimeUtils/setCurrentMillisSystem))))
(defn create-demo-data! []
(db/add-api-key! {:apikey 55 :comment "Finna"})
(create-demo-users-and-roles!)
(let [res1 (:id (db/create-resource! {:resid "urn:nbn:fi:lb-201403262" :organization "nbn" :owneruserid (+demo-users+ :owner) :modifieruserid (+demo-users+ :owner)}))
res2 (:id (db/create-resource! {:resid "Extra Data" :organization "nbn" :owneruserid (+demo-users+ :owner) :modifieruserid (+demo-users+ :owner)}))
form (create-basic-form! +demo-users+)
workflows (create-workflows! +demo-users+)]
(create-resource-license! res2 "Some demo license" (+demo-users+ :owner))
(create-expired-license!)
(let [dynamic (create-catalogue-item! res1 (:dynamic workflows) form
{"en" "Dynamic workflow" "fi" "Dynaaminen työvuo"})]
(create-dynamic-applications! dynamic (:dynamic workflows) +demo-users+))
(let [thlform (create-thl-demo-form! +demo-users+)
thl-catid (create-catalogue-item! res1 (:dynamic workflows) thlform {"en" "THL catalogue item" "fi" "THL katalogi-itemi"})]
(create-member-applications! thl-catid (:dynamic workflows) (+demo-users+ :applicant1) (+demo-users+ :approver1) [{:userid (+demo-users+ :applicant2)}]))
(let [dynamic-disabled (create-catalogue-item! res1 (:dynamic workflows) form
{"en" "Dynamic workflow (disabled)"
"fi" "Dynaaminen työvuo (pois käytöstä)"})]
(create-disabled-applications! dynamic-disabled (:dynamic workflows) (+demo-users+ :approver1) (+demo-users+ :approver1))
(db/set-catalogue-item-state! {:id dynamic-disabled :enabled false}))))