Skip to content

Commit e09f7e8

Browse files
committed
tests(schema): add compile-only harness (deny http/https via policy) and 3 more OpenRPC fragment unit tests (openrpc, servers, components) to build toward IT (#29)
1 parent cd630dd commit e09f7e8

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import jdk.sandbox.java.util.json.JsonValue;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.net.URI;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
import java.util.Set;
11+
12+
import static org.assertj.core.api.Assertions.assertThat;
13+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
14+
15+
/// Compile-only posture: deny all remote fetches to reveal which fragments
16+
/// compile locally. This is a unit-level gate prior to the full OpenRPC IT.
17+
class OpenRPCCompileOnlyTest extends JsonSchemaLoggingConfig {
18+
19+
@Test
20+
void compile_local_fragment_succeeds_with_remote_denied() {
21+
final var fragment = "{" +
22+
"\"$defs\":{\"X\":{\"type\":\"integer\"}}," +
23+
"\"$ref\":\"#/$defs/X\"" +
24+
"}";
25+
26+
final var fetcher = new MapRemoteFetcher(Map.of());
27+
final var policy = JsonSchema.FetchPolicy.defaults().withAllowedSchemes(Set.of("file"));
28+
final var options = JsonSchema.CompileOptions.remoteDefaults(fetcher).withFetchPolicy(policy);
29+
30+
final var schema = JsonSchema.compile(Json.parse(fragment), JsonSchema.Options.DEFAULT, options);
31+
assertThat(schema.validate(Json.parse("1")).valid()).isTrue();
32+
assertThat(schema.validate(Json.parse("\"x\""))).extracting("valid").isEqualTo(false);
33+
}
34+
35+
@Test
36+
void compile_remote_ref_is_denied_by_policy() {
37+
final var fragment = "{" +
38+
"\"$ref\":\"http://example.com/openrpc.json#/$defs/X\"" +
39+
"}";
40+
41+
final var fetcher = new MapRemoteFetcher(Map.of());
42+
final var policy = JsonSchema.FetchPolicy.defaults().withAllowedSchemes(Set.of("file"));
43+
final var options = JsonSchema.CompileOptions.remoteDefaults(fetcher).withFetchPolicy(policy);
44+
45+
assertThatThrownBy(() -> JsonSchema.compile(Json.parse(fragment), JsonSchema.Options.DEFAULT, options))
46+
.isInstanceOf(JsonSchema.RemoteResolutionException.class)
47+
.hasFieldOrPropertyWithValue("reason", JsonSchema.RemoteResolutionException.Reason.POLICY_DENIED)
48+
.hasMessageContaining("http://example.com/openrpc.json");
49+
}
50+
51+
private static final class MapRemoteFetcher implements JsonSchema.RemoteFetcher {
52+
private final Map<URI, JsonValue> documents;
53+
private MapRemoteFetcher(Map<URI, JsonValue> documents) { this.documents = Map.copyOf(documents); }
54+
@Override public FetchResult fetch(URI uri, JsonSchema.FetchPolicy policy) {
55+
throw new JsonSchema.RemoteResolutionException(uri,
56+
JsonSchema.RemoteResolutionException.Reason.NOT_FOUND,
57+
"No remote document registered for " + uri);
58+
}
59+
}
60+
}

json-java21-schema/src/test/java/io/github/simbo1905/json/schema/OpenRPCFragmentsUnitTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,45 @@ void method_object_requires_name_and_params() {
5252
assertThat(missing.valid()).isFalse();
5353
}
5454

55+
@Test
56+
void openrpc_field_is_non_empty_string() {
57+
final var schema = JsonSchema.compile(Json.parse(
58+
"{" +
59+
"\"type\":\"object\"," +
60+
"\"required\":[\"openrpc\"]," +
61+
"\"properties\":{\"openrpc\":{\"type\":\"string\",\"minLength\":1}}" +
62+
"}"
63+
));
64+
assertThat(schema.validate(Json.parse("{\"openrpc\":\"1.3.0\"}"))).extracting("valid").isEqualTo(true);
65+
assertThat(schema.validate(Json.parse("{\"openrpc\":\"\"}"))).extracting("valid").isEqualTo(false);
66+
assertThat(schema.validate(Json.parse("{\"openrpc\":1}"))).extracting("valid").isEqualTo(false);
67+
}
68+
69+
@Test
70+
void servers_array_items_are_objects() {
71+
final var schema = JsonSchema.compile(Json.parse(
72+
"{" +
73+
"\"type\":\"object\"," +
74+
"\"properties\":{\"servers\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}}}" +
75+
"}"
76+
));
77+
assertThat(schema.validate(Json.parse("{\"servers\":[{}]}"))).extracting("valid").isEqualTo(true);
78+
assertThat(schema.validate(Json.parse("{\"servers\":[1,2,3]}"))).extracting("valid").isEqualTo(false);
79+
}
80+
81+
@Test
82+
void components_object_accepts_any_members() {
83+
final var schema = JsonSchema.compile(Json.parse(
84+
"{" +
85+
"\"type\":\"object\"," +
86+
"\"properties\":{\"components\":{\"type\":\"object\"}}," +
87+
"\"additionalProperties\":true" +
88+
"}"
89+
));
90+
assertThat(schema.validate(Json.parse("{\"components\":{\"x\":1}}"))).extracting("valid").isEqualTo(true);
91+
assertThat(schema.validate(Json.parse("{\"components\":1}"))).extracting("valid").isEqualTo(false);
92+
}
93+
5594
@Test
5695
void param_object_requires_name_and_allows_schema_object() {
5796
LOG.info(() -> "TEST: " + getClass().getSimpleName() + "#param_object_requires_name_and_allows_schema_object");

0 commit comments

Comments
 (0)