7
7
import static com .github .paulcwarren .ginkgo4j .Ginkgo4jDSL .It ;
8
8
import static internal .org .springframework .content .jpa .StoreIT .getContextName ;
9
9
import static org .hamcrest .CoreMatchers .is ;
10
+ import static org .hamcrest .CoreMatchers .not ;
10
11
import static org .hamcrest .MatcherAssert .assertThat ;
11
12
import static org .hamcrest .Matchers .greaterThan ;
12
13
import static org .hamcrest .Matchers .notNullValue ;
16
17
import java .io .ByteArrayInputStream ;
17
18
import java .io .IOException ;
18
19
import java .io .InputStream ;
20
+ import java .util .UUID ;
19
21
import java .util .function .Supplier ;
20
22
23
+ import javax .persistence .Entity ;
24
+ import javax .persistence .GeneratedValue ;
25
+ import javax .persistence .GenerationType ;
26
+ import javax .persistence .Id ;
27
+ import javax .persistence .Table ;
28
+
21
29
import org .apache .commons .io .IOUtils ;
22
30
import org .junit .Assert ;
23
31
import org .junit .runner .RunWith ;
32
+ import org .springframework .content .commons .annotations .ContentId ;
33
+ import org .springframework .content .commons .annotations .ContentLength ;
34
+ import org .springframework .content .commons .annotations .GenericGenerator ;
35
+ import org .springframework .content .commons .repository .ContentStore ;
36
+ import org .springframework .content .commons .store .ValueGenerator ;
24
37
import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
38
+ import org .springframework .data .jpa .repository .JpaRepository ;
25
39
import org .springframework .transaction .PlatformTransactionManager ;
26
40
import org .springframework .transaction .TransactionStatus ;
27
41
import org .springframework .transaction .support .DefaultTransactionDefinition ;
39
53
import internal .org .springframework .content .jpa .testsupport .models .ClaimForm ;
40
54
import internal .org .springframework .content .jpa .testsupport .repositories .ClaimRepository ;
41
55
import internal .org .springframework .content .jpa .testsupport .stores .ClaimFormStore ;
56
+ import lombok .Getter ;
57
+ import lombok .NoArgsConstructor ;
58
+ import lombok .Setter ;
42
59
43
60
@ RunWith (Ginkgo4jRunner .class )
44
61
@ Ginkgo4jConfiguration (threads = 1 )
45
62
public class ContentStoreIT {
46
63
47
64
private static Class <?>[] CONFIG_CLASSES = new Class []{
48
- H2Config .class ,
49
- HSQLConfig .class ,
50
- MySqlConfig .class ,
51
- PostgresConfig .class ,
65
+ H2Config .class ,
66
+ HSQLConfig .class ,
67
+ MySqlConfig .class ,
68
+ PostgresConfig .class ,
52
69
SqlServerConfig .class
53
70
};
54
71
55
72
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ();
56
-
73
+
57
74
// for postgres (large object api operations must be in a transaction)
58
75
private PlatformTransactionManager ptm ;
59
76
@@ -67,41 +84,41 @@ public class ContentStoreIT {
67
84
Describe ("ContentStore" , () -> {
68
85
69
86
for (Class <?> configClass : CONFIG_CLASSES ) {
70
-
87
+
71
88
Context (getContextName (configClass ), () -> {
72
-
89
+
73
90
BeforeEach (() -> {
74
91
context = new AnnotationConfigApplicationContext ();
75
92
context .register (TestConfig .class );
76
93
context .register (configClass );
77
94
context .refresh ();
78
-
95
+
79
96
ptm = context .getBean (PlatformTransactionManager .class );
80
97
claimRepo = context .getBean (ClaimRepository .class );
81
98
claimFormStore = context .getBean (ClaimFormStore .class );
82
-
99
+
83
100
if (ptm == null ) {
84
101
ptm = mock (PlatformTransactionManager .class );
85
102
}
86
103
});
87
-
104
+
88
105
AfterEach (() -> {
89
106
deleteAllClaimFormsContent ();
90
107
deleteAllClaims ();
91
108
});
92
-
109
+
93
110
Context ("given an Entity with content" , () -> {
94
-
111
+
95
112
BeforeEach (() -> {
96
113
claim = new Claim ();
97
114
claim .setFirstName ("John" );
98
115
claim .setLastName ("Smith" );
99
116
claim .setClaimForm (new ClaimForm ());
100
117
claim = claimRepo .save (claim );
101
-
118
+
102
119
claimFormStore .setContent (claim .getClaimForm (), new ByteArrayInputStream ("Hello Spring Content World!" .getBytes ()));
103
120
});
104
-
121
+
105
122
It ("should be able to store new content" , () -> {
106
123
doInTransaction (ptm , () -> {
107
124
try (InputStream content = claimFormStore .getContent (claim .getClaimForm ())) {
@@ -110,32 +127,32 @@ public class ContentStoreIT {
110
127
return null ;
111
128
});
112
129
});
113
-
130
+
114
131
It ("should have content metadata" , () -> {
115
132
Assert .assertThat (claim .getClaimForm ().getContentId (), is (notNullValue ()));
116
133
Assert .assertThat (claim .getClaimForm ().getContentId ().trim ().length (), greaterThan (0 ));
117
134
Assert .assertEquals (claim .getClaimForm ().getContentLength (), 27L );
118
135
});
119
-
136
+
120
137
Context ("when content is updated" , () -> {
121
138
BeforeEach (() ->{
122
139
claimFormStore .setContent (claim .getClaimForm (), new ByteArrayInputStream ("Hello Updated Spring Content World!" .getBytes ()));
123
140
claim = claimRepo .save (claim );
124
141
});
125
-
142
+
126
143
It ("should have the updated content" , () -> {
127
144
doInTransaction (ptm , () -> {
128
145
boolean matches = false ;
129
146
try (InputStream content = claimFormStore .getContent (claim .getClaimForm ())) {
130
147
matches = IOUtils .contentEquals (new ByteArrayInputStream ("Hello Updated Spring Content World!" .getBytes ()), content );
131
148
assertThat (matches , is (true ));
132
149
} catch (IOException e ) {
133
- }
150
+ }
134
151
return null ;
135
152
});
136
153
});
137
154
});
138
-
155
+
139
156
Context ("when content is updated with shorter content" , () -> {
140
157
BeforeEach (() -> {
141
158
claimFormStore .setContent (claim .getClaimForm (), new ByteArrayInputStream ("Hello Spring World!" .getBytes ()));
@@ -148,39 +165,78 @@ public class ContentStoreIT {
148
165
matches = IOUtils .contentEquals (new ByteArrayInputStream ("Hello Spring World!" .getBytes ()), content );
149
166
assertThat (matches , is (true ));
150
167
} catch (IOException e ) {
151
- }
168
+ }
152
169
return null ;
153
170
});
154
171
});
155
172
});
156
-
173
+
157
174
Context ("when content is deleted" , () -> {
158
175
BeforeEach (() -> {
159
176
id = claim .getClaimForm ().getContentId ();
160
177
claimFormStore .unsetContent (claim .getClaimForm ());
161
178
claim = claimRepo .save (claim );
162
179
});
163
-
180
+
164
181
AfterEach (() -> {
165
182
claimRepo .delete (claim );
166
183
});
167
-
184
+
168
185
It ("should have no content" , () -> {
169
186
ClaimForm deletedClaimForm = new ClaimForm ();
170
187
deletedClaimForm .setContentId ((String )id );
171
-
188
+
172
189
doInTransaction (ptm , () -> {
173
190
try (InputStream content = claimFormStore .getContent (deletedClaimForm )) {
174
191
Assert .assertThat (content , is (nullValue ()));
175
192
} catch (IOException e ) {
176
193
}
177
- return null ;
194
+ return null ;
178
195
});
179
-
196
+
180
197
Assert .assertThat (claim .getClaimForm ().getContentId (), is (nullValue ()));
181
198
Assert .assertEquals (claim .getClaimForm ().getContentLength (), 0 );
182
199
});
183
200
});
201
+
202
+ Context ("when content is updated and the content id field is computed from a custom value generator" , () -> {
203
+
204
+ It ("should assign a new content Id" , () -> {
205
+
206
+ TEntityWithGenRepository repoWithGen = context .getBean (TEntityWithGenRepository .class );
207
+ TEntityWithGenStore storeWithGen = context .getBean (TEntityWithGenStore .class );
208
+
209
+ ContentStoreIT .TEntityWithGenerator entity = new ContentStoreIT .TEntityWithGenerator ();
210
+ entity = storeWithGen .setContent (entity , new ByteArrayInputStream ("Hello Spring Content World!" .getBytes ()));
211
+ entity = repoWithGen .save (entity );
212
+ String firstContentId = entity .getContentId ();
213
+
214
+ entity = storeWithGen .setContent (entity , new ByteArrayInputStream ("Hello Spring Content World!" .getBytes ()));
215
+ entity = repoWithGen .save (entity );
216
+ String secondContentId = entity .getContentId ();
217
+
218
+ assertThat (firstContentId , is (not (secondContentId )));
219
+ });
220
+ });
221
+
222
+ Context ("when content is updated and the content id field is not computed" , () -> {
223
+
224
+ It ("should assign a new content Id" , () -> {
225
+
226
+ claim = new Claim ();
227
+ claim .setClaimForm (new ClaimForm ());
228
+ claim = claimRepo .save (claim );
229
+ claimFormStore .setContent (claim .getClaimForm (), new ByteArrayInputStream ("Hello Spring Content World!" .getBytes ()));
230
+ claim = claimRepo .save (claim );
231
+ String firstContentId = claim .getClaimForm ().getContentId ();
232
+
233
+ claimFormStore .setContent (claim .getClaimForm (), new ByteArrayInputStream ("Hello Spring Content World!" .getBytes ()));
234
+ claim = claimRepo .save (claim );
235
+ String secondContentId = claim .getClaimForm ().getContentId ();
236
+
237
+ assertThat (firstContentId , is (secondContentId ));
238
+ });
239
+ });
184
240
});
185
241
});
186
242
}
@@ -197,7 +253,7 @@ public static <T> T doInTransaction(PlatformTransactionManager ptm, Supplier<T>
197
253
} catch (Exception e ) {
198
254
ptm .rollback (status );
199
255
}
200
-
256
+
201
257
return null ;
202
258
}
203
259
@@ -206,7 +262,7 @@ protected boolean hasContent(ClaimForm claimForm) {
206
262
if (claimForm == null ) {
207
263
return false ;
208
264
}
209
-
265
+
210
266
boolean exists = doInTransaction (ptm , () -> {
211
267
try (InputStream content = claimFormStore .getContent (claimForm )) {
212
268
if (content != null ) {
@@ -248,4 +304,41 @@ protected void deleteAllClaimFormsContent() {
248
304
}
249
305
}
250
306
}
307
+
308
+ @ Entity
309
+ @ Getter
310
+ @ Setter
311
+ @ NoArgsConstructor
312
+ @ Table (name ="tentity_with_generator" )
313
+ public static class TEntityWithGenerator {
314
+
315
+ @ Id
316
+ @ GeneratedValue (strategy =GenerationType .AUTO )
317
+ private Long id ;
318
+
319
+ @ ContentId
320
+ @ GenericGenerator (strategy =ContentStoreIT .TestContentIdGenerator .class )
321
+ private String contentId ;
322
+
323
+ @ ContentLength
324
+ private long contentLen ;
325
+ }
326
+
327
+ public interface TEntityWithGenRepository extends JpaRepository <TEntityWithGenerator , String > {}
328
+ public interface TEntityWithGenStore extends ContentStore <TEntityWithGenerator , String > {}
329
+
330
+ public static class TestContentIdGenerator implements ValueGenerator <ContentStoreIT .TEntityWithGenerator , String > {
331
+
332
+ @ Override
333
+ public String generate (TEntityWithGenerator entity ) {
334
+
335
+ return UUID .randomUUID ().toString ();
336
+ }
337
+
338
+ @ Override
339
+ public boolean regenerate (TEntityWithGenerator entity ) {
340
+
341
+ return true ;
342
+ }
343
+ }
251
344
}
0 commit comments