An ATProto Lexicon validator for Gleam.
1import gleam/json
2import gleeunit
3import gleeunit/should
4import honk/validation/context
5import honk/validation/meta/unknown
6
7pub fn main() {
8 gleeunit.main()
9}
10
11// ========== SCHEMA VALIDATION TESTS ==========
12
13pub fn valid_unknown_schema_test() {
14 let schema = json.object([#("type", json.string("unknown"))])
15
16 let assert Ok(ctx) = context.builder() |> context.build
17
18 unknown.validate_schema(schema, ctx) |> should.be_ok
19}
20
21pub fn valid_unknown_schema_with_description_test() {
22 let schema =
23 json.object([
24 #("type", json.string("unknown")),
25 #("description", json.string("Flexible data following ATProto rules")),
26 ])
27
28 let assert Ok(ctx) = context.builder() |> context.build
29
30 unknown.validate_schema(schema, ctx) |> should.be_ok
31}
32
33pub fn invalid_unknown_schema_extra_fields_test() {
34 let schema =
35 json.object([
36 #("type", json.string("unknown")),
37 #("extraField", json.string("not allowed")),
38 ])
39
40 let assert Ok(ctx) = context.builder() |> context.build
41
42 unknown.validate_schema(schema, ctx) |> should.be_error
43}
44
45// ========== DATA VALIDATION TESTS ==========
46
47pub fn valid_unknown_data_simple_object_test() {
48 let schema = json.object([#("type", json.string("unknown"))])
49 let data = json.object([#("a", json.string("alphabet")), #("b", json.int(3))])
50
51 let assert Ok(ctx) = context.builder() |> context.build
52
53 unknown.validate_data(data, schema, ctx) |> should.be_ok
54}
55
56pub fn valid_unknown_data_with_type_field_test() {
57 let schema = json.object([#("type", json.string("unknown"))])
58 let data =
59 json.object([
60 #("$type", json.string("example.lexicon.record#demoObject")),
61 #("a", json.int(1)),
62 #("b", json.int(2)),
63 ])
64
65 let assert Ok(ctx) = context.builder() |> context.build
66
67 unknown.validate_data(data, schema, ctx) |> should.be_ok
68}
69
70pub fn valid_unknown_data_nested_objects_test() {
71 let schema = json.object([#("type", json.string("unknown"))])
72 let data =
73 json.object([
74 #("outer", json.object([#("inner", json.string("nested"))])),
75 #("count", json.int(42)),
76 ])
77
78 let assert Ok(ctx) = context.builder() |> context.build
79
80 unknown.validate_data(data, schema, ctx) |> should.be_ok
81}
82
83pub fn valid_unknown_data_empty_object_test() {
84 let schema = json.object([#("type", json.string("unknown"))])
85 let data = json.object([])
86
87 let assert Ok(ctx) = context.builder() |> context.build
88
89 unknown.validate_data(data, schema, ctx) |> should.be_ok
90}
91
92pub fn invalid_unknown_data_boolean_test() {
93 let schema = json.object([#("type", json.string("unknown"))])
94 let data = json.bool(False)
95
96 let assert Ok(ctx) = context.builder() |> context.build
97
98 unknown.validate_data(data, schema, ctx) |> should.be_error
99}
100
101pub fn invalid_unknown_data_string_test() {
102 let schema = json.object([#("type", json.string("unknown"))])
103 let data = json.string("not an object")
104
105 let assert Ok(ctx) = context.builder() |> context.build
106
107 unknown.validate_data(data, schema, ctx) |> should.be_error
108}
109
110pub fn invalid_unknown_data_integer_test() {
111 let schema = json.object([#("type", json.string("unknown"))])
112 let data = json.int(123)
113
114 let assert Ok(ctx) = context.builder() |> context.build
115
116 unknown.validate_data(data, schema, ctx) |> should.be_error
117}
118
119pub fn invalid_unknown_data_array_test() {
120 let schema = json.object([#("type", json.string("unknown"))])
121 let data = json.preprocessed_array([json.int(1), json.int(2), json.int(3)])
122
123 let assert Ok(ctx) = context.builder() |> context.build
124
125 unknown.validate_data(data, schema, ctx) |> should.be_error
126}
127
128pub fn invalid_unknown_data_null_test() {
129 let schema = json.object([#("type", json.string("unknown"))])
130 let data = json.null()
131
132 let assert Ok(ctx) = context.builder() |> context.build
133
134 unknown.validate_data(data, schema, ctx) |> should.be_error
135}
136
137pub fn invalid_unknown_data_bytes_object_test() {
138 let schema = json.object([#("type", json.string("unknown"))])
139 // Bytes object: {"$bytes": "base64-string"}
140 let data = json.object([#("$bytes", json.string("SGVsbG8gd29ybGQ="))])
141
142 let assert Ok(ctx) = context.builder() |> context.build
143
144 unknown.validate_data(data, schema, ctx) |> should.be_error
145}
146
147pub fn invalid_unknown_data_blob_object_test() {
148 let schema = json.object([#("type", json.string("unknown"))])
149 // Blob object: {"$type": "blob", ...}
150 let data =
151 json.object([
152 #("$type", json.string("blob")),
153 #("mimeType", json.string("text/plain")),
154 #("size", json.int(12_345)),
155 ])
156
157 let assert Ok(ctx) = context.builder() |> context.build
158
159 unknown.validate_data(data, schema, ctx) |> should.be_error
160}