1 package org.linkedopenactors.rdfpub.uc;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
5 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6
7 import java.io.IOException;
8 import java.io.StringReader;
9 import java.io.UnsupportedEncodingException;
10 import java.util.Optional;
11 import java.util.Set;
12 import java.util.stream.Collectors;
13 import java.util.stream.StreamSupport;
14
15 import org.eclipse.rdf4j.model.IRI;
16 import org.eclipse.rdf4j.model.Model;
17 import org.eclipse.rdf4j.model.Statement;
18 import org.eclipse.rdf4j.model.vocabulary.RDF;
19 import org.eclipse.rdf4j.rio.RDFFormat;
20 import org.eclipse.rdf4j.rio.Rio;
21 import org.linkedopenactors.rdfpub.domain.Activity;
22 import org.linkedopenactors.rdfpub.domain.ActivityPubObject;
23 import org.linkedopenactors.rdfpub.domain.Actor;
24 import org.linkedopenactors.rdfpub.domain.DomainObjectBuilders;
25 import org.linkedopenactors.rdfpub.domain.Instance;
26 import org.linkedopenactors.rdfpub.rdf4j.ModelToRdfObject;
27 import org.springframework.http.HttpHeaders;
28 import org.springframework.security.oauth2.core.oidc.StandardClaimNames;
29 import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
30 import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.JwtRequestPostProcessor;
31 import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
32 import org.springframework.test.web.servlet.MockMvc;
33 import org.springframework.test.web.servlet.MvcResult;
34 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
35 import org.springframework.web.context.WebApplicationContext;
36
37 public class TestHelperV2 {
38
39 private WebApplicationContext context;
40
41 private DomainObjectBuilders domainObjectBuilders;
42
43 private MockMvc mockMvc;
44
45 private ModelToRdfObject modelToRdfObject;
46
47 public TestHelperV2(WebApplicationContext context, ModelToRdfObject modelToRdfObject, DomainObjectBuilders domainObjectBuilders) {
48 this.context = context;
49 this.modelToRdfObject = modelToRdfObject;
50 this.domainObjectBuilders = domainObjectBuilders;
51 this.mockMvc = MockMvcBuilders
52 .webAppContextSetup(this.context)
53 .apply(SecurityMockMvcConfigurers.springSecurity())
54 .build();
55 }
56
57 public Actor createActor(String userId, String preferredUsername, String issuer) throws Exception {
58 JwtRequestPostProcessor jwt = jwt(userId, preferredUsername, issuer);
59
60 MvcResult mvcResultActor = this.getMockMvc().perform(get("/api/whoami")
61 .with(jwt)
62 .header(HttpHeaders.ACCEPT, "text/turtle"))
63 .andExpect(status().isOk())
64 .andReturn();
65
66 return toActor(mvcResultActor).orElseThrow();
67 }
68
69 private Optional<Actor> toActor(MvcResult mvcResultActor) throws UnsupportedEncodingException, IOException {
70 return toRdfObject(mvcResultActor)
71 .map(rdfo->domainObjectBuilders.actorBuilder().rdfObject(rdfo).build());
72 }
73
74 public Optional<ActivityPubObject> toActivityPubObject(MvcResult mvcResultActor) throws UnsupportedEncodingException, IOException {
75 return toRdfObject(mvcResultActor)
76 .map(o->domainObjectBuilders.activityPubObjectBuilder().rdfObject(o).build());
77 }
78
79 public Optional<Activity> toActivity(MvcResult mvcResultActor) throws UnsupportedEncodingException, IOException {
80 return toRdfObject(mvcResultActor)
81 .map(o->domainObjectBuilders.activityPubObjectBuilder().rdfObject(o).build())
82 .map(ap->domainObjectBuilders.activityBuilder().rdfObject(ap).build());
83
84 }
85
86 public Optional<Instance> toInstance(MvcResult mvcResultActor) throws UnsupportedEncodingException, IOException {
87 return toRdfObject(mvcResultActor)
88 .map(o->domainObjectBuilders.activityPubObjectBuilder().rdfObject(o).build())
89 .map(ap->domainObjectBuilders.instanceBuilder().rdfObject(ap).build());
90 }
91
92 private Optional<ActivityPubObject> toRdfObject(MvcResult mvcResultActor) throws UnsupportedEncodingException, IOException {
93 StringReader sr = new StringReader(mvcResultActor.getResponse().getContentAsString());
94 Model m = Rio.parse(sr, RDFFormat.TURTLE);
95 Set<IRI> subjects = StreamSupport.stream(m.getStatements(null, RDF.TYPE, null).spliterator(), false)
96 .map(Statement::getSubject)
97 .map(IRI.class::cast)
98 .collect(Collectors.toSet());
99 if(subjects.isEmpty()) {
100 return Optional.empty();
101 } else {
102 assertEquals(1, subjects.size());
103 }
104 IRI s = subjects.stream().findFirst().orElseThrow();
105 ActivityPubObject rdfo = modelToRdfObject.toActivityPubObject(s, m);
106 return Optional.ofNullable(rdfo);
107 }
108
109 public MockMvc getMockMvc() {
110 return mockMvc;
111 }
112
113 public JwtRequestPostProcessor jwt(String userId, String preferredUsername, String issuer) {
114 return SecurityMockMvcRequestPostProcessors.jwt().jwt(j -> {
115 j.claim(StandardClaimNames.SUB, userId);
116 j.claim(StandardClaimNames.PREFERRED_USERNAME, preferredUsername);
117 j.claim("iss", issuer);
118 });
119 }
120 }