1 package org.linkedopenactors.rdfpub.uc;
2
3 import static org.eclipse.rdf4j.model.util.Values.iri;
4 import static org.eclipse.rdf4j.model.util.Values.literal;
5 import static org.junit.jupiter.api.Assertions.assertEquals;
6 import static org.junit.jupiter.api.Assertions.assertNotNull;
7 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
8 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
9 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
10 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
11
12 import java.io.StringReader;
13 import java.io.StringWriter;
14 import java.math.BigInteger;
15 import java.util.Random;
16 import java.util.Set;
17 import java.util.UUID;
18
19 import org.apache.commons.lang3.RandomStringUtils;
20 import org.eclipse.rdf4j.model.IRI;
21 import org.eclipse.rdf4j.model.Literal;
22 import org.eclipse.rdf4j.model.Model;
23 import org.eclipse.rdf4j.model.util.ModelBuilder;
24 import org.eclipse.rdf4j.model.util.Models;
25 import org.eclipse.rdf4j.model.util.Values;
26 import org.eclipse.rdf4j.model.vocabulary.RDF;
27 import org.eclipse.rdf4j.rio.RDFFormat;
28 import org.eclipse.rdf4j.rio.Rio;
29 import org.junit.jupiter.api.Test;
30 import org.linkedopenactors.rdfpub.TestingWebApplication;
31 import org.linkedopenactors.rdfpub.domain.Actor;
32 import org.springframework.beans.factory.annotation.Autowired;
33 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
34 import org.springframework.boot.test.context.SpringBootTest;
35 import org.springframework.http.HttpHeaders;
36 import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.JwtRequestPostProcessor;
37 import org.springframework.test.context.ActiveProfiles;
38 import org.springframework.test.context.TestPropertySource;
39 import org.springframework.test.web.servlet.MvcResult;
40
41 import de.naturzukunft.rdf4j.vocabulary.AS;
42 import de.naturzukunft.rdf4j.vocabulary.SCHEMA_ORG;
43
44 @SpringBootTest(classes = TestingWebApplication.class)
45 @AutoConfigureMockMvc
46 @ActiveProfiles("test")
47 @TestPropertySource(properties = "app.rdfRepositoryHome=target/repoManager/TestSendCreateActivityAndUpdateIt")
48 class TestSendCreateActivityAndUpdateIt {
49
50 @Autowired
51 private TestHelperV2 testHelperV2;
52
53
54 @Test
55 void testAlreadyExists() throws Exception {
56
57 String userId = Integer.toString(new Random().ints(1111, 9999).findFirst().getAsInt());
58 String preferredUsername = RandomStringUtils.random(10, true, false);
59 Actor actor = testHelperV2.createActor(userId, preferredUsername, "http://example.com");
60
61 JwtRequestPostProcessor jwt = testHelperV2.jwt(userId, preferredUsername, "http://example.com");
62 IRI objectId = iri(actor.getSubject().toString() + "/someObject");
63
64 String objectIdentifier = UUID.randomUUID().toString();
65 Literal nameLiteral = literal("Max Mustermann");
66
67
68 Model activity = new ModelBuilder()
69 .subject("http://example.com/someActivity")
70 .add(RDF.TYPE, AS.Create)
71 .add(AS.object, objectId)
72 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
73 .add(SCHEMA_ORG.identifier, UUID.randomUUID())
74 .subject(objectId)
75 .add(RDF.TYPE, AS.Object)
76 .add(SCHEMA_ORG.name, nameLiteral)
77 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
78 .add(SCHEMA_ORG.identifier, objectIdentifier)
79 .build();
80
81 StringWriter sw = new StringWriter();
82 Rio.write(activity, sw, RDFFormat.JSONLD);
83
84
85 MvcResult mvcResult = testHelperV2.getMockMvc().perform(post(actor.getOutboxEndpoint().toString())
86 .with(jwt)
87 .content(sw.toString())
88 .contentType("application/ld+json")
89 .header(HttpHeaders.ACCEPT, "application/ld+json"))
90 .andExpect(status().isCreated())
91 .andReturn();
92
93 String activityLocation = mvcResult.getResponse().getHeader(HttpHeaders.LOCATION);
94 assertNotNull(activityLocation);
95
96
97 mvcResult = testHelperV2.getMockMvc().perform(get(activityLocation)
98 .with(jwt)
99 .header(HttpHeaders.ACCEPT, "application/ld+json"))
100 .andExpect(status().isOk())
101 .andDo(print())
102 .andReturn();
103 StringReader sr = new StringReader(mvcResult.getResponse().getContentAsString());
104 Model reReadActivity = Rio.parse(sr, RDFFormat.JSONLD);
105
106 objectId = Models.getPropertyIRI(reReadActivity, Values.iri(activityLocation), AS.object).orElseThrow();
107
108
109 Literal nameLiteralUpdated = literal("Max Updated");
110 Model updateActivity = new ModelBuilder()
111 .subject("http://example.com/someActivity")
112 .add(RDF.TYPE, AS.Update)
113 .add(AS.object, objectId)
114 .add(SCHEMA_ORG.identifier, UUID.randomUUID())
115 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
116 .subject(objectId)
117 .add(RDF.TYPE, AS.Object)
118 .add(SCHEMA_ORG.name, nameLiteralUpdated)
119 .add(SCHEMA_ORG.identifier, objectIdentifier)
120 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
121 .build();
122
123 sw = new StringWriter();
124 Rio.write(updateActivity, sw, RDFFormat.JSONLD);
125
126 Set<org.linkedopenactors.rdfpub.domain.IRI> ctx = Set.of(actor.getSubject(), actor.getOutboxEndpoint());
127
128 mvcResult = testHelperV2.getMockMvc().perform(post(actor.getOutboxEndpoint().toString())
129 .with(jwt)
130 .content(sw.toString())
131 .contentType("application/ld+json")
132 .header(HttpHeaders.ACCEPT, "application/ld+json"))
133 .andExpect(status().isBadRequest())
134 .andExpect( status().reason( "object with version 1, identifier: " + objectIdentifier + ", types: [https://www.w3.org/ns/activitystreams#Object], contexts: "+ctx+" already exists!" ) )
135 .andReturn();
136 }
137
138 @Test
139 void test() throws Exception {
140 String userId = Integer.toString(new Random().ints(1111, 9999).findFirst().getAsInt());
141 String preferredUsername = RandomStringUtils.random(10, true, false);
142 Actor actor = testHelperV2.createActor(userId, preferredUsername, "http://example.com");
143
144 JwtRequestPostProcessor jwt = testHelperV2.jwt(userId, preferredUsername, "http://example.com");
145 IRI objectId = iri(actor.getSubject().toString() + "/someObject");
146
147 String objectIdentifier = UUID.randomUUID().toString();
148 Literal nameLiteral = literal("Max Mustermann");
149
150 Model activity = new ModelBuilder()
151 .subject("http://example.com/someActivity")
152 .add(RDF.TYPE, AS.Create)
153 .add(AS.object, objectId)
154 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
155 .add(SCHEMA_ORG.identifier, UUID.randomUUID())
156 .subject(objectId)
157 .add(RDF.TYPE, AS.Object)
158 .add(SCHEMA_ORG.name, nameLiteral)
159 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
160 .add(SCHEMA_ORG.identifier, objectIdentifier)
161 .build();
162
163
164 StringWriter sw = new StringWriter();
165 Rio.write(activity, sw, RDFFormat.JSONLD);
166
167 MvcResult mvcResult = testHelperV2.getMockMvc().perform(post(actor.getOutboxEndpoint().toString())
168 .with(jwt)
169 .content(sw.toString())
170 .contentType("application/ld+json")
171 .header(HttpHeaders.ACCEPT, "application/ld+json"))
172 .andExpect(status().isCreated())
173 .andReturn();
174
175 String activityLocation = mvcResult.getResponse().getHeader(HttpHeaders.LOCATION);
176 assertNotNull(activityLocation);
177
178 mvcResult = testHelperV2.getMockMvc().perform(get(activityLocation)
179 .with(jwt)
180 .header(HttpHeaders.ACCEPT, "application/ld+json"))
181 .andExpect(status().isOk())
182 .andDo(print())
183 .andReturn();
184
185 StringReader sr = new StringReader(mvcResult.getResponse().getContentAsString());
186 Model reReadActivity = Rio.parse(sr, RDFFormat.JSONLD);
187
188 objectId = Models.getPropertyIRI(reReadActivity, Values.iri(activityLocation), AS.object).orElseThrow();
189
190 Literal nameLiteralUpdated = literal("Max Updated");
191 Model updateActivity = new ModelBuilder()
192 .subject("http://example.com/someActivity")
193 .add(RDF.TYPE, AS.Update)
194 .add(AS.object, objectId)
195 .add(SCHEMA_ORG.identifier, UUID.randomUUID())
196 .add(SCHEMA_ORG.version, BigInteger.valueOf(1L))
197 .subject(objectId)
198 .add(RDF.TYPE, AS.Object)
199 .add(SCHEMA_ORG.name, nameLiteralUpdated)
200 .add(SCHEMA_ORG.identifier, objectIdentifier)
201 .add(SCHEMA_ORG.version, BigInteger.valueOf(2L))
202 .build();
203
204 sw = new StringWriter();
205 Rio.write(updateActivity, sw, RDFFormat.JSONLD);
206
207 mvcResult = testHelperV2.getMockMvc().perform(post(actor.getOutboxEndpoint().toString())
208 .with(jwt)
209 .content(sw.toString())
210 .contentType("application/ld+json")
211 .header(HttpHeaders.ACCEPT, "application/ld+json"))
212 .andExpect(status().isCreated())
213 .andReturn();
214
215 String updateActivityLocation = mvcResult.getResponse().getHeader(HttpHeaders.LOCATION);
216 assertNotNull(updateActivityLocation);
217
218 mvcResult = testHelperV2.getMockMvc().perform(get(updateActivityLocation)
219 .with(jwt)
220 .header(HttpHeaders.ACCEPT, "application/ld+json"))
221 .andExpect(status().isOk())
222 .andDo(print())
223 .andReturn();
224
225 sr = new StringReader(mvcResult.getResponse().getContentAsString());
226 Model reReadUpdatedActivity = Rio.parse(sr, RDFFormat.JSONLD);
227
228 IRI updatedObjectId = Models.getPropertyIRI(reReadUpdatedActivity, Values.iri(updateActivityLocation), AS.object).orElseThrow();
229
230 mvcResult = testHelperV2.getMockMvc().perform(get(updatedObjectId.stringValue())
231 .with(jwt)
232 .header(HttpHeaders.ACCEPT, "application/ld+json"))
233 .andExpect(status().isOk())
234 .andDo(print())
235 .andReturn();
236
237 sr = new StringReader(mvcResult.getResponse().getContentAsString());
238 Model updatedObject = Rio.parse(sr, RDFFormat.JSONLD);
239 assertEquals(nameLiteralUpdated, Models.getPropertyLiteral(updatedObject, updatedObjectId, SCHEMA_ORG.name).orElseThrow());
240 assertEquals(2L, Models.getPropertyLiteral(updatedObject, updatedObjectId, SCHEMA_ORG.version).orElseThrow().longValue());
241 assertEquals(objectIdentifier, Models.getPropertyLiteral(updatedObject, updatedObjectId, SCHEMA_ORG.identifier).orElseThrow().stringValue());
242 }
243 }