• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chiefonboarding / ChiefOnboarding / 17705301273

14 Sep 2025 02:37AM UTC coverage: 89.705% (-0.002%) from 89.707%
17705301273

push

github

web-flow
Fix deprecation warnings (#570)

6953 of 7751 relevant lines covered (89.7%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.24
back/admin/integrations/builder_forms.py
1
from crispy_forms.helper import FormHelper
1✔
2
from crispy_forms.layout import Div, Field, Layout
1✔
3
from django import forms
1✔
4
from django.contrib.postgres.forms import SimpleArrayField
1✔
5
from django.utils.translation import gettext_lazy as _
1✔
6

7
from admin.integrations.utils import (
1✔
8
    convert_array_to_object,
9
    prepare_initial_data,
10
)
11
from admin.integrations.validators import (
1✔
12
    validate_continue_if,
13
    validate_ID,
14
    validate_polling,
15
    validate_status_code,
16
)
17
from admin.templates.forms import FieldWithExtraContext
1✔
18

19

20
class JSONToDict(forms.JSONField):
1✔
21
    def clean(self, value):
1✔
22
        value = super().clean(value)
×
23
        if isinstance(value, list):
×
24
            value = convert_array_to_object(value)
×
25
        return value
×
26

27

28
class ValueKeyArrayField(FieldWithExtraContext):
1✔
29
    template = "value_key_array_field.html"
1✔
30

31

32
class IntegerListField(FieldWithExtraContext):
1✔
33
    template = "manifest_test/integer_list_field.html"
1✔
34

35

36
class ManifestFormForm(forms.Form):
1✔
37
    id = forms.CharField(
1✔
38
        label="ID",
39
        help_text=_(
40
            "This value can be used in the other calls. Please do not use spaces or weird characters. A single word in capitals is prefered."
41
        ),
42
        validators=[validate_ID],
43
    )
44
    name = forms.CharField(
1✔
45
        label="Name", help_text=_("The form label shown to the admin")
46
    )
47
    type = forms.ChoiceField(
1✔
48
        choices=(("choice", "choice"), ("input", "input")),
49
        label="Type",
50
        help_text=_(
51
            "If you choose choice, you will be able to set the options yourself OR fetch from an external url."
52
        ),
53
    )
54
    options_source = forms.ChoiceField(
1✔
55
        choices=(("fixed list", "fixed list"), ("fetch url", "fetch url")),
56
        initial="fixed list",
57
    )
58

59
    # fixed items
60
    items = forms.JSONField(
1✔
61
        initial=list,
62
        help_text=_(
63
            "Use only if you set type to 'choice'. This is for fixed items (if you don't want to fetch from a URL)"
64
        ),
65
        required=False,
66
    )
67

68
    # dynamic choices
69
    url = forms.URLField(
1✔
70
        max_length=255,
71
        help_text=_("The url it should fetch the options from."),
72
        required=False,
73
        assume_scheme="https",
74
    )
75
    method = forms.ChoiceField(
1✔
76
        choices=(
77
            ("GET", "GET"),
78
            ("POST", "POST"),
79
            ("PUT", "PUT"),
80
            ("DELETE", "DELETE"),
81
        ),
82
        initial="GET",
83
        label=_("Request method"),
84
    )
85
    data = forms.JSONField(initial=dict, required=False)
1✔
86
    cast_data_to_json = forms.BooleanField(
1✔
87
        initial=True,
88
        help_text=_(
89
            "Check this if the data should be send as json. When unchecked, it's send as a string."
90
        ),
91
        required=False,
92
    )
93
    headers = JSONToDict(
1✔
94
        initial=list,
95
        help_text=_("(optionally) This will overwrite the default headers."),
96
        required=False,
97
    )
98
    data_from = forms.CharField(
1✔
99
        max_length=255,
100
        initial="",
101
        help_text=_(
102
            "The property it should use from the response of the url if you need to go deeper into the result."
103
        ),
104
        required=False,
105
    )
106
    choice_value = forms.CharField(
1✔
107
        max_length=255,
108
        initial="id",
109
        help_text=_(
110
            "The value it should take for using in other parts of the integration"
111
        ),
112
        required=False,
113
    )
114
    choice_name = forms.CharField(
1✔
115
        max_length=255,
116
        initial="name",
117
        help_text=_("The name that should be displayed to the admin as an option."),
118
        required=False,
119
    )
120

121
    def __init__(self, disabled=False, *args, **kwargs):
1✔
122
        super().__init__(*args, **kwargs)
×
123
        self.helper = FormHelper()
×
124
        self.helper.form_tag = False
×
125
        self.initial = prepare_initial_data(self.initial)
×
126

127
        if disabled:
×
128
            for field in self.fields:
×
129
                self.fields[field].disabled = True
×
130

131
        show_manual_items = "d-none"
×
132
        show_fetch_url = ""
×
133
        show_choice_options = ""
×
134
        if self.initial.get("options_source", "fixed list") == "fixed list":
×
135
            show_manual_items = ""
×
136
            show_fetch_url = "d-none"
×
137

138
        if self.initial.get("type", "") == "input":
×
139
            show_choice_options = "d-none"
×
140

141
        self.helper.layout = Layout(
×
142
            Div(
143
                Div(Field("id"), css_class="col-6"),
144
                Div(Field("name"), css_class="col-6"),
145
                css_class="row",
146
            ),
147
            Div(
148
                Div(Field("type"), css_class="col-6"),
149
                Div(Field("options_source"), css_class=f"col-6 {show_choice_options}"),
150
                css_class="row",
151
            ),
152
            Div(
153
                ValueKeyArrayField("items", extra_context={"disabled": disabled}),
154
                css_class=f"manual_items {show_manual_items} {show_choice_options}",
155
            ),
156
            Div(
157
                Div(
158
                    Div(Field("method"), css_class="col-3"),
159
                    Div(Field("url"), css_class="col-9"),
160
                    css_class="row",
161
                ),
162
                Div(Field("data_from")),
163
                Div(Field("data")),
164
                Div(Field("cast_data_to_json")),
165
                Div(
166
                    Div(Field("choice_value"), css_class="col-6"),
167
                    Div(Field("choice_name"), css_class="col-6"),
168
                    css_class="row",
169
                ),
170
                ValueKeyArrayField("headers", extra_context={"disabled": disabled}),
171
                css_class=f"fetch_items {show_fetch_url} {show_choice_options}",
172
            ),
173
        )
174

175

176
class ManifestRevokeForm(forms.Form):
1✔
177
    url = forms.URLField(
1✔
178
        max_length=255,
179
        help_text=_("The url it should fetch the options from."),
180
        required=False,
181
        assume_scheme="https",
182
    )
183
    method = forms.ChoiceField(
1✔
184
        choices=(
185
            ("GET", "GET"),
186
            ("POST", "POST"),
187
            ("PUT", "PUT"),
188
            ("PATCH", "PATCH"),
189
            ("DELETE", "DELETE"),
190
        ),
191
        initial="GET",
192
        label=_("Request method"),
193
        required=False,
194
    )
195
    data = forms.JSONField(initial=dict, required=False)
1✔
196
    cast_data_to_json = forms.BooleanField(
1✔
197
        initial=True,
198
        help_text=_(
199
            "Check this if the data should be send as json. When unchecked, it's send as a string."
200
        ),
201
        required=False,
202
    )
203
    expected = forms.CharField(initial="", required=False)
1✔
204
    status_code = SimpleArrayField(
1✔
205
        forms.CharField(max_length=1000), required=False, initial=list
206
    )
207
    headers = JSONToDict(
1✔
208
        initial=list,
209
        help_text=_("(optionally) This will overwrite the default headers."),
210
        required=False,
211
    )
212

213
    def __init__(self, disabled=False, *args, **kwargs):
1✔
214
        super().__init__(*args, **kwargs)
×
215
        self.helper = FormHelper()
×
216
        self.helper.form_tag = False
×
217
        self.initial = prepare_initial_data(self.initial)
×
218

219
        if disabled:
×
220
            for field in self.fields:
×
221
                self.fields[field].disabled = True
×
222

223
        self.helper.layout = Layout(
×
224
            Div(
225
                Div(
226
                    Div(Field("method"), css_class="col-3"),
227
                    Div(Field("url"), css_class="col-9"),
228
                    css_class="row",
229
                ),
230
                Div(Field("data")),
231
                Div(Field("cast_data_to_json")),
232
                Div(Field("expected")),
233
                IntegerListField("status_code", extra_context={"disabled": disabled}),
234
                ValueKeyArrayField("headers", extra_context={"disabled": disabled}),
235
            )
236
        )
237

238

239
class ManifestHeadersForm(forms.Form):
1✔
240
    headers = forms.JSONField(
1✔
241
        initial=list,
242
        help_text=_("(optionally) This will overwrite the default headers."),
243
        required=False,
244
    )
245

246
    def __init__(self, *args, **kwargs):
1✔
247
        super().__init__(*args, **kwargs)
×
248
        self.helper = FormHelper()
×
249
        self.helper.form_tag = False
×
250

251
        self.helper.layout = Layout(ValueKeyArrayField("headers"))
×
252

253

254
class ManifestOauthForm(forms.Form):
1✔
255
    oauth = forms.JSONField(
1✔
256
        initial=list, help_text=_("OAuth settings"), required=False, label="OAuth"
257
    )
258

259
    def __init__(self, *args, **kwargs):
1✔
260
        super().__init__(*args, **kwargs)
×
261
        self.helper = FormHelper()
×
262
        self.helper.form_tag = False
×
263

264

265
class ManifestExtractDataForm(forms.Form):
1✔
266
    action = forms.ChoiceField(
1✔
267
        choices=(("create", "create"), ("sync", "sync")),
268
        initial="create",
269
    )
270
    data_from = forms.CharField(
1✔
271
        max_length=255,
272
        initial="",
273
        help_text=_(
274
            "The property it should use from the response of the url if you need to go deeper into the result."
275
        ),
276
        required=False,
277
    )
278
    data_structure = forms.JSONField(
1✔
279
        initial=dict,
280
        help_text=_("How to map the data to the user"),
281
        required=True,
282
        label="Data structure",
283
    )
284
    schedule = forms.CharField(
1✔
285
        max_length=255,
286
        initial="",
287
        help_text=_("cron type schedule for running this in the background"),
288
        required=False,
289
    )
290
    amount_pages_to_fetch = forms.IntegerField(
1✔
291
        initial=5,
292
        label=_("Paginated response: amount pages to fetch"),
293
        help_text=_(
294
            "Maximum amount of page to fetch. It will stop earlier if there are no users found anymore."
295
        ),
296
        required=False,
297
    )
298
    next_page_token_from = forms.CharField(
1✔
299
        max_length=255,
300
        label=_("Paginated response: Next page token from"),
301
        initial="",
302
        help_text=_(
303
            "The place to look for the next page token. You can use the dot notation to do go deeper into the JSON. If it's not found, it will stop."
304
        ),
305
        required=False,
306
    )
307
    next_page = forms.CharField(
1✔
308
        max_length=255,
309
        label=_("Paginated response: Next page url"),
310
        initial="",
311
        help_text=_(
312
            "A fixed url that will be used to fetch the new result in combination with the 'Next page token from'"
313
        ),
314
        required=False,
315
    )
316
    next_page_from = forms.CharField(
1✔
317
        max_length=255,
318
        label=_("Paginated response: Next page from"),
319
        initial="",
320
        help_text=_(
321
            "The place to look for the next page url (if not using 'next_page' and 'next_page_token_from'. You can use the dot notation to do go deeper into the JSON. If it's not found, it will stop."
322
        ),
323
        required=False,
324
    )
325

326
    def __init__(self, *args, **kwargs):
1✔
327
        super().__init__(*args, **kwargs)
×
328
        self.helper = FormHelper()
×
329
        self.helper.form_tag = False
×
330

331

332
class ManifestExistsForm(forms.Form):
1✔
333
    url = forms.URLField(
1✔
334
        max_length=255,
335
        help_text=_("The url it should check"),
336
        required=False,
337
        assume_scheme="https",
338
    )
339
    method = forms.ChoiceField(
1✔
340
        choices=(
341
            ("GET", "GET"),
342
            ("POST", "POST"),
343
            ("PUT", "PUT"),
344
            ("DELETE", "DELETE"),
345
        ),
346
        initial="GET",
347
        label=_("Request method"),
348
        required=False,
349
    )
350
    expected = forms.CharField(initial="", required=False)
1✔
351
    status_code = SimpleArrayField(
1✔
352
        forms.CharField(max_length=1000),
353
        required=False,
354
        initial=[],
355
        validators=[validate_status_code],
356
    )
357
    headers = forms.JSONField(
1✔
358
        initial=list,
359
        help_text=_("(optionally) This will overwrite the default headers."),
360
        required=False,
361
    )
362

363
    def __init__(self, *args, **kwargs):
1✔
364
        super().__init__(*args, **kwargs)
×
365
        self.helper = FormHelper()
×
366
        self.helper.form_tag = False
×
367
        self.initial = prepare_initial_data(self.initial)
×
368

369
        self.helper.layout = Layout(
×
370
            Div(
371
                Div(Field("method"), css_class="col-3"),
372
                Div(Field("url"), css_class="col-9"),
373
                css_class="row",
374
            ),
375
            Div(
376
                Field("expected"),
377
            ),
378
            Div(
379
                IntegerListField("status_code"),
380
            ),
381
            ValueKeyArrayField("headers"),
382
        )
383

384

385
class ManifestInitialDataForm(forms.Form):
1✔
386
    id = forms.CharField(
1✔
387
        max_length=100,
388
        help_text=_(
389
            "This value can be used in the other calls. Please do not use spaces or weird characters. A single word in capitals is prefered."
390
        ),
391
        validators=[validate_ID],
392
    )
393
    name = forms.CharField(
1✔
394
        max_length=255,
395
        help_text=_(
396
            "Type 'generate' if you want this value to be generated on the fly (different for each execution), will not need to be filled by a user"
397
        ),
398
    )
399
    description = forms.CharField(
1✔
400
        max_length=1255,
401
        help_text=_("This will be shown under the input field for extra context"),
402
        required=False,
403
    )
404
    secret = forms.BooleanField(
1✔
405
        initial=False,
406
        help_text="Enable this if the value should always be masked",
407
        required=False,
408
    )
409

410
    def __init__(self, disabled=False, *args, **kwargs):
1✔
411
        super().__init__(*args, **kwargs)
×
412
        self.helper = FormHelper()
×
413
        self.helper.form_tag = False
×
414

415
        if disabled:
×
416
            for field in self.fields:
×
417
                self.fields[field].disabled = True
×
418

419
        self.helper.layout = Layout(
×
420
            Div(
421
                Div(Field("id"), css_class="col-9"),
422
                Div(Field("secret"), css_class="col-3"),
423
                css_class="row",
424
            ),
425
            Div(
426
                Field("name"),
427
            ),
428
            Div(
429
                Field("description"),
430
            ),
431
        )
432

433

434
class ManifestUserInfoForm(forms.Form):
1✔
435
    id = forms.CharField(
1✔
436
        max_length=100,
437
        help_text=_(
438
            "This value can be used in the other calls. Please do not use spaces or weird characters. A single word in capitals is prefered."
439
        ),
440
        validators=[validate_ID],
441
    )
442
    name = forms.CharField(max_length=255)
1✔
443
    description = forms.CharField(
1✔
444
        max_length=1255,
445
        help_text=_("This will be shown under the input field for extra context"),
446
    )
447

448
    def __init__(self, disabled=False, *args, **kwargs):
1✔
449
        super().__init__(*args, **kwargs)
×
450
        self.helper = FormHelper()
×
451
        self.helper.form_tag = False
×
452

453
        if disabled:
×
454
            for field in self.fields:
×
455
                self.fields[field].disabled = True
×
456

457
        self.helper.layout = Layout(
×
458
            Div(
459
                Field("id"),
460
            ),
461
            Div(
462
                Field("name"),
463
            ),
464
            Div(
465
                Field("description"),
466
            ),
467
        )
468

469

470
class ManifestExecuteForm(forms.Form):
1✔
471
    url = forms.URLField(
1✔
472
        max_length=255,
473
        help_text=_("The url it should trigger"),
474
        required=False,
475
        assume_scheme="https",
476
    )
477
    method = forms.ChoiceField(
1✔
478
        choices=(
479
            ("GET", "GET"),
480
            ("POST", "POST"),
481
            ("PUT", "PUT"),
482
            ("PATCH", "PATCH"),
483
            ("DELETE", "DELETE"),
484
        ),
485
        initial="GET",
486
        label=_("Request method"),
487
        required=False,
488
    )
489
    status_code = SimpleArrayField(
1✔
490
        forms.CharField(max_length=1000), required=False, initial=[]
491
    )
492
    cast_data_to_json = forms.BooleanField(
1✔
493
        initial=True,
494
        help_text=_(
495
            "Check this if the data should be send as json. When unchecked, it's send as a string."
496
        ),
497
        required=False,
498
    )
499
    headers = forms.JSONField(
1✔
500
        initial=list,
501
        help_text=_("(optionally) This will overwrite the default headers."),
502
        required=False,
503
    )
504
    data = forms.JSONField(initial=dict, required=False)
1✔
505
    store_data = forms.JSONField(
1✔
506
        initial=dict,
507
        help_text=_(
508
            "(optionally) if you want to store data that's the request returns, then you can do that here."
509
        ),
510
        required=False,
511
    )
512
    continue_if = forms.JSONField(
1✔
513
        initial=dict,
514
        help_text=_("(optionally) set up a condition to block any further requests"),
515
        required=False,
516
        validators=[validate_continue_if],
517
    )
518
    polling = forms.JSONField(
1✔
519
        initial=dict,
520
        help_text=_(
521
            "(optionally) rerun this request a specific amount of times until it passes"
522
        ),
523
        required=False,
524
        validators=[validate_polling],
525
    )
526
    save_as_file = forms.CharField(
1✔
527
        initial="",
528
        help_text=_(
529
            "(optionally) if this request returns a file, then you can save it to use later"
530
        ),
531
        required=False,
532
    )
533
    files = forms.JSONField(
1✔
534
        initial=dict,
535
        help_text=_(
536
            "(optionally) if you want to use any of the previous files to submit"
537
        ),
538
        required=False,
539
    )
540

541
    class Meta:
1✔
542
        fields = (
1✔
543
            "url",
544
            "method",
545
            "data",
546
            "headers",
547
            "store_data",
548
            "continue_if",
549
            "polling",
550
            "save_as_file",
551
            "files",
552
        )
553

554
    def __init__(self, disabled=False, *args, **kwargs):
1✔
555
        super().__init__(*args, **kwargs)
×
556
        self.helper = FormHelper()
×
557
        self.helper.form_tag = False
×
558
        self.initial = prepare_initial_data(self.initial)
×
559

560
        if disabled:
×
561
            for field in self.fields:
×
562
                self.fields[field].disabled = True
×
563

564
        self.helper.layout = Layout(
×
565
            Div(
566
                Div(
567
                    Div(Field("method"), css_class="col-3"),
568
                    Div(Field("url"), css_class="col-9"),
569
                    css_class="row",
570
                ),
571
                Div(Field("data")),
572
                Div(Field("cast_data_to_json")),
573
                Div(Field("store_data")),
574
                Div(Field("continue_if")),
575
                Div(Field("polling")),
576
                Div(Field("save_as_file")),
577
                Div(Field("files")),
578
                ValueKeyArrayField("headers", extra_context={"disabled": disabled}),
579
            )
580
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc