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

chiefonboarding / ChiefOnboarding / 22208900060

20 Feb 2026 02:30AM UTC coverage: 90.5% (-0.08%) from 90.58%
22208900060

Pull #621

github

web-flow
Merge 2acae0dac into b47beee8a
Pull Request #621: Pritunl compatibility

8183 of 9042 relevant lines covered (90.5%)

0.9 hits per line

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

97.94
back/admin/integrations/serializers.py
1
from django.core.exceptions import ValidationError
1✔
2
from django_q.models import validate_cron
1✔
3
from rest_framework import serializers
1✔
4

5

6
# Credit: https://stackoverflow.com/a/42432240
7
class ValidateMixin:
1✔
8
    def validate(self, data):
1✔
9
        if hasattr(self, "initial_data"):
1✔
10
            unknown_keys = set(self.initial_data.keys()) - set(self.fields.keys())
1✔
11
            if unknown_keys:
1✔
12
                raise ValidationError("Got unknown fields: {}".format(unknown_keys))
×
13
        return data
1✔
14

15

16
class ManifestFormSerializer(ValidateMixin, serializers.Serializer):
1✔
17
    id = serializers.CharField()
1✔
18
    url = serializers.CharField(required=False)
1✔
19
    name = serializers.CharField()
1✔
20
    type = serializers.ChoiceField(
1✔
21
        [
22
            ("multiple_choice", "Multiple choice"),
23
            ("choice", "Choice"),
24
            ("input", "Input field"),
25
            ("generate", "Generate random text"),
26
        ]
27
    )
28
    items = serializers.JSONField(required=False)
1✔
29
    data_from = serializers.CharField(required=False)
1✔
30
    choice_value = serializers.CharField(required=False)
1✔
31
    choice_name = serializers.CharField(required=False)
1✔
32
    options_source = serializers.ChoiceField(
1✔
33
        [
34
            ("fixed list", "fixed list"),
35
            ("fetch url", "fetch url"),
36
        ],
37
        required=False,
38
    )
39

40

41
class ManifestConditionSerializer(ValidateMixin, serializers.Serializer):
1✔
42
    response_notation = serializers.CharField()
1✔
43
    value = serializers.CharField()
1✔
44

45

46
class ManifestPollingSerializer(ValidateMixin, serializers.Serializer):
1✔
47
    interval = serializers.IntegerField(min_value=1, max_value=3600)
1✔
48
    amount = serializers.IntegerField(min_value=1, max_value=100)
1✔
49

50

51
class ManifestExistSerializer(ValidateMixin, serializers.Serializer):
1✔
52
    url = serializers.CharField()
1✔
53
    expected = serializers.CharField()
1✔
54
    status_code = serializers.ListField(
1✔
55
        child=serializers.IntegerField(), required=False
56
    )
57
    method = serializers.ChoiceField(
1✔
58
        [
59
            ("GET", "GET"),
60
            ("POST", "POST"),
61
            ("PUT", "PUT"),
62
        ]
63
    )
64

65

66
class ManifestExecuteSerializer(ValidateMixin, serializers.Serializer):
1✔
67
    url = serializers.CharField()
1✔
68
    data = serializers.JSONField(required=False, default=dict)
1✔
69
    headers = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
70
    store_data = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
71
    method = serializers.ChoiceField(
1✔
72
        [
73
            ("HEAD", "HEAD"),
74
            ("GET", "GET"),
75
            ("POST", "POST"),
76
            ("PUT", "PUT"),
77
            ("PATCH", "PATCH"),
78
            ("DELETE", "DELETE"),
79
        ]
80
    )
81
    extra_headers = serializers.ChoiceField(
1✔
82
        [
83
            ("prituln", "prituln"),
84
        ],
85
        required=False,
86
    )
87
    status_code = serializers.ListField(
1✔
88
        child=serializers.IntegerField(), required=False
89
    )
90
    files = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
91
    save_as_file = serializers.CharField(required=False)
1✔
92
    polling = ManifestPollingSerializer(required=False)
1✔
93
    continue_if = ManifestConditionSerializer(required=False)
1✔
94

95
    def validate(self, data):
1✔
96
        # Check that if polling has been filled, that continue_if is also filled
97
        polling = data.get("polling", False)
1✔
98
        continue_if = data.get("continue_if", False)
1✔
99
        if polling and not continue_if:
1✔
100
            raise serializers.ValidationError(
×
101
                "continue_if must be filled if you use polling"
102
            )
103
        return data
1✔
104

105

106
class ManifestRevokeSerializer(ValidateMixin, serializers.Serializer):
1✔
107
    url = serializers.CharField()
1✔
108
    data = serializers.JSONField(required=False, default=dict)
1✔
109
    status_code = serializers.ListField(
1✔
110
        child=serializers.IntegerField(), required=False
111
    )
112
    headers = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
113
    method = serializers.ChoiceField(
1✔
114
        [
115
            ("HEAD", "HEAD"),
116
            ("GET", "GET"),
117
            ("POST", "POST"),
118
            ("PUT", "PUT"),
119
            ("PATCH", "PATCH"),
120
            ("DELETE", "DELETE"),
121
        ]
122
    )
123

124

125
class ManifestPostExecuteNotificationSerializer(ValidateMixin, serializers.Serializer):
1✔
126
    type = serializers.ChoiceField(
1✔
127
        [
128
            ("email", "Email message"),
129
            ("text", "Text message"),
130
        ]
131
    )
132
    to = serializers.CharField()
1✔
133
    subject = serializers.CharField()
1✔
134
    message = serializers.CharField()
1✔
135

136

137
class ManifestInitialDataFormSerializer(ValidateMixin, serializers.Serializer):
1✔
138
    id = serializers.CharField()
1✔
139
    name = serializers.CharField()
1✔
140
    secret = serializers.BooleanField(default=True)
1✔
141
    description = serializers.CharField()
1✔
142

143

144
class ManifestExtraUserInfoFormSerializer(ValidateMixin, serializers.Serializer):
1✔
145
    id = serializers.CharField()
1✔
146
    name = serializers.CharField()
1✔
147
    description = serializers.CharField()
1✔
148

149

150
class ManifestOauthSerializer(ValidateMixin, serializers.Serializer):
1✔
151
    authenticate_url = serializers.CharField()
1✔
152
    access_token = ManifestExecuteSerializer(required=True)
1✔
153
    refresh = ManifestExecuteSerializer(required=True)
1✔
154
    without_code = serializers.BooleanField(required=False)
1✔
155

156

157
class WebhookManifestSerializer(ValidateMixin, serializers.Serializer):
1✔
158
    form = ManifestFormSerializer(required=False, many=True)
1✔
159
    exists = ManifestExistSerializer(required=False)
1✔
160
    revoke = ManifestRevokeSerializer(required=False, many=True)
1✔
161
    execute = ManifestExecuteSerializer(many=True)
1✔
162
    post_execute_notification = ManifestPostExecuteNotificationSerializer(
1✔
163
        many=True, required=False
164
    )
165
    initial_data_form = ManifestInitialDataFormSerializer(many=True, required=False)
1✔
166
    extra_user_info = ManifestExtraUserInfoFormSerializer(many=True, required=False)
1✔
167
    headers = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
168
    oauth = ManifestOauthSerializer(required=False)
1✔
169

170

171
class SyncUsersManifestSerializer(ValidateMixin, serializers.Serializer):
1✔
172
    data_from = serializers.CharField(required=False)
1✔
173
    data_structure = serializers.DictField(child=serializers.CharField())
1✔
174
    execute = ManifestExecuteSerializer(many=True)
1✔
175
    next_page_token_from = serializers.CharField(required=False)
1✔
176
    next_page = serializers.CharField(required=False)
1✔
177
    next_page_from = serializers.CharField(required=False)
1✔
178
    schedule = serializers.CharField(required=False, validators=[validate_cron])
1✔
179
    action = serializers.ChoiceField([("create", "create"), ("update", "update")])
1✔
180
    amount_pages_to_fetch = serializers.IntegerField(required=False)
1✔
181
    initial_data_form = ManifestInitialDataFormSerializer(many=True, required=False)
1✔
182
    headers = serializers.DictField(child=serializers.CharField(), default=dict)
1✔
183
    oauth = ManifestOauthSerializer(required=False)
1✔
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