1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.search.solr.internal.metadata

File DocumentSolrMetadataExtractorTest.java

 

Code metrics

0
252
20
1
636
449
23
0.09
12.6
20
1.15

Classes

Class Line # Actions
DocumentSolrMetadataExtractorTest 91 252 0% 23 1
0.996323599.6%
 

Contributing tests

This file is covered by 13 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.search.solr.internal.metadata;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.InputStream;
24    import java.util.ArrayList;
25    import java.util.Arrays;
26    import java.util.Collection;
27    import java.util.Collections;
28    import java.util.Date;
29    import java.util.List;
30    import java.util.Locale;
31   
32    import javax.inject.Provider;
33   
34    import org.apache.commons.io.IOUtils;
35    import org.apache.solr.common.SolrInputDocument;
36    import org.hamcrest.MatcherAssert;
37    import org.hamcrest.Matchers;
38    import org.junit.Before;
39    import org.junit.Rule;
40    import org.junit.Test;
41    import org.mockito.AdditionalAnswers;
42    import org.mockito.invocation.InvocationOnMock;
43    import org.mockito.stubbing.Answer;
44    import org.xwiki.context.Execution;
45    import org.xwiki.context.ExecutionContext;
46    import org.xwiki.model.EntityType;
47    import org.xwiki.model.reference.AttachmentReference;
48    import org.xwiki.model.reference.DocumentReference;
49    import org.xwiki.model.reference.EntityReference;
50    import org.xwiki.model.reference.EntityReferenceSerializer;
51    import org.xwiki.rendering.block.Block;
52    import org.xwiki.rendering.renderer.BlockRenderer;
53    import org.xwiki.rendering.renderer.printer.WikiPrinter;
54    import org.xwiki.search.solr.internal.api.FieldUtils;
55    import org.xwiki.search.solr.internal.api.SolrFieldNameEncoder;
56    import org.xwiki.search.solr.internal.api.SolrIndexerException;
57    import org.xwiki.search.solr.internal.reference.SolrReferenceResolver;
58    import org.xwiki.test.mockito.MockitoComponentMockingRule;
59   
60    import com.xpn.xwiki.XWiki;
61    import com.xpn.xwiki.XWikiContext;
62    import com.xpn.xwiki.XWikiException;
63    import com.xpn.xwiki.doc.XWikiAttachment;
64    import com.xpn.xwiki.doc.XWikiDocument;
65    import com.xpn.xwiki.objects.BaseObject;
66    import com.xpn.xwiki.objects.BaseProperty;
67    import com.xpn.xwiki.objects.classes.BaseClass;
68    import com.xpn.xwiki.objects.classes.BooleanClass;
69    import com.xpn.xwiki.objects.classes.ListItem;
70    import com.xpn.xwiki.objects.classes.PasswordClass;
71    import com.xpn.xwiki.objects.classes.StaticListClass;
72    import com.xpn.xwiki.objects.classes.StringClass;
73    import com.xpn.xwiki.objects.classes.TextAreaClass;
74   
75    import static org.junit.Assert.assertEquals;
76    import static org.junit.Assert.assertNull;
77    import static org.junit.Assert.assertSame;
78    import static org.junit.Assert.assertTrue;
79    import static org.junit.Assert.fail;
80    import static org.mockito.ArgumentMatchers.any;
81    import static org.mockito.ArgumentMatchers.same;
82    import static org.mockito.Mockito.doAnswer;
83    import static org.mockito.Mockito.mock;
84    import static org.mockito.Mockito.when;
85   
86    /**
87    * Unit tests for document meta data extraction.
88    *
89    * @version $Id: 894705f088a4752c8f18a644135d82a6560bc0dd $
90    */
 
91    public class DocumentSolrMetadataExtractorTest
92    {
93    @Rule
94    public final MockitoComponentMockingRule<SolrMetadataExtractor> mocker =
95    new MockitoComponentMockingRule<SolrMetadataExtractor>(DocumentSolrMetadataExtractor.class);
96   
97    private XWikiContext xcontext = mock(XWikiContext.class);
98   
99    /**
100    * The document from which we extract the meta data.
101    */
102    private XWikiDocument document = mock(XWikiDocument.class);
103   
104    private XWikiDocument translatedDocument = mock(XWikiDocument.class, Locale.FRENCH.toString());
105   
106    private DocumentReference documentReference =
107    new DocumentReference("wiki", Arrays.asList("Path", "To", "Page"), "WebHome");
108   
109    private DocumentReference frenchDocumentReference = new DocumentReference(this.documentReference, Locale.FRENCH);
110   
 
111  13 toggle @Before
112    public void setUp() throws Exception
113    {
114  13 this.mocker.registerMockComponent(SolrReferenceResolver.class, "document");
115   
116    // XWikiContext Provider
117  13 Provider<XWikiContext> xcontextProvider = this.mocker.registerMockComponent(XWikiContext.TYPE_PROVIDER);
118  13 when(xcontextProvider.get()).thenReturn(this.xcontext);
119   
120    // XWikiContext trough Execution
121  13 ExecutionContext executionContext = new ExecutionContext();
122  13 executionContext.setProperty(XWikiContext.EXECUTIONCONTEXT_KEY, this.xcontext);
123  13 Execution execution = this.mocker.registerMockComponent(Execution.class);
124  13 when(execution.getContext()).thenReturn(executionContext);
125   
126    // XWiki
127  13 XWiki wiki = mock(XWiki.class);
128  13 when(this.xcontext.getWiki()).thenReturn(wiki);
129   
130    // XWikiDocument
131  13 when(wiki.getDocument(this.documentReference, this.xcontext)).thenReturn(this.document);
132  13 when(this.document.getDocumentReference()).thenReturn(this.documentReference);
133  13 when(this.document.isHidden()).thenReturn(false);
134  13 when(this.document.getLocale()).thenReturn(Locale.ROOT);
135  13 when(this.document.getRealLocale()).thenReturn(Locale.US);
136   
137  13 when(this.document.getTranslatedDocument(Locale.FRENCH, this.xcontext)).thenReturn(this.translatedDocument);
138  13 when(this.translatedDocument.getRealLocale()).thenReturn(Locale.FRENCH);
139  13 when(this.translatedDocument.getLocale()).thenReturn(Locale.FRENCH);
140  13 when(this.translatedDocument.getDocumentReference()).thenReturn(this.frenchDocumentReference);
141   
142    // Field Name Serializer
143  13 EntityReferenceSerializer<String> fieldNameSerializer =
144    this.mocker.getInstance(EntityReferenceSerializer.TYPE_STRING, "solr");
145  13 when(fieldNameSerializer.serialize(any())).then(new Answer<String>()
146    {
 
147  24 toggle @Override
148    public String answer(InvocationOnMock invocation) throws Throwable
149    {
150  24 EntityReference reference = (EntityReference) invocation.getArguments()[0];
151  24 StringBuilder result = new StringBuilder();
152  24 for (EntityReference parent : reference.getReversedReferenceChain()) {
153  60 result.append('.').append(parent.getName());
154    }
155  24 return result.substring(1);
156    }
157    });
158   
159    // Field Name Encoder
160  13 SolrFieldNameEncoder fieldNameEncoder = this.mocker.getInstance(SolrFieldNameEncoder.class);
161  13 when(fieldNameEncoder.encode(any())).then(AdditionalAnswers.returnsFirstArg());
162    }
163   
 
164  1 toggle @Test
165    public void getSimpleDocument() throws Exception
166    {
167    //
168    // Mock
169    //
170   
171    // ID
172  1 String id = "wiki:Space.Name_" + Locale.ROOT.toString();
173  1 SolrReferenceResolver documentSolrReferenceResolver =
174    this.mocker.getInstance(SolrReferenceResolver.class, "document");
175  1 when(documentSolrReferenceResolver.getId(documentReference)).thenReturn(id);
176   
177    // Full Name
178  1 String fullName = "Space.Name";
179  1 EntityReferenceSerializer<String> localEntityReferenceSerializer =
180    this.mocker.registerMockComponent(EntityReferenceSerializer.TYPE_STRING, "local");
181  1 when(localEntityReferenceSerializer.serialize(this.documentReference)).thenReturn(fullName);
182   
183    // Hierarchy
184  1 when(localEntityReferenceSerializer.serialize(this.documentReference.getParent())).thenReturn("Path.To.Page");
185  1 when(localEntityReferenceSerializer.serialize(this.documentReference.getParent().getParent()))
186    .thenReturn("Path.To");
187  1 when(localEntityReferenceSerializer.serialize(this.documentReference.getParent().getParent().getParent()))
188    .thenReturn("Path");
189   
190    // Creator.
191  1 DocumentReference creatorReference = new DocumentReference("wiki", "Space", "Creator");
192  1 when(this.document.getCreatorReference()).thenReturn(creatorReference);
193   
194  1 String creatorStringReference = "wiki:Space.Creator";
195  1 EntityReferenceSerializer<String> entityReferenceSerializer =
196    this.mocker.registerMockComponent(EntityReferenceSerializer.TYPE_STRING, "default");
197  1 when(entityReferenceSerializer.serialize(creatorReference)).thenReturn(creatorStringReference);
198   
199  1 String creatorDisplayName = "Crea Tor";
200  1 when(this.xcontext.getWiki().getPlainUserName(creatorReference, this.xcontext)).thenReturn(creatorDisplayName);
201   
202    // Author.
203  1 DocumentReference authorReference = new DocumentReference("wiki", "Space", "Author");
204  1 when(this.document.getAuthorReference()).thenReturn(authorReference);
205   
206  1 String authorStringReference = "wiki:Space.Author";
207  1 when(entityReferenceSerializer.serialize(authorReference)).thenReturn(authorStringReference);
208   
209  1 String authorDisplayName = "Au Thor";
210  1 when(this.xcontext.getWiki().getPlainUserName(authorReference, this.xcontext)).thenReturn(authorDisplayName);
211   
212    // Creation Date
213  1 Date creationDate = new Date();
214  1 when(this.document.getCreationDate()).thenReturn(creationDate);
215   
216    // Date
217  1 Date date = new Date();
218  1 when(this.document.getContentUpdateDate()).thenReturn(date);
219   
220    // Version
221  1 String version = "1.1";
222  1 when(this.document.getVersion()).thenReturn(version);
223   
224    // Version summary
225  1 String comment = "1.1 comment";
226  1 when(this.document.getComment()).thenReturn(comment);
227   
228    // XObjects.
229  1 when(this.document.getXObjects()).thenReturn(Collections.<DocumentReference, List<BaseObject>>emptyMap());
230   
231    // Title
232  1 String title = "title";
233  1 when(this.document.getRenderedTitle(any(), same(this.xcontext))).thenReturn(title);
234   
235    // Rendered Content
236  1 final String renderedContent = "rendered content";
237  1 BlockRenderer plainRenderer = this.mocker.registerMockComponent(BlockRenderer.class, "plain/1.0");
238  1 doAnswer(new Answer<Void>()
239    {
 
240  1 toggle @Override
241    public Void answer(InvocationOnMock invocation)
242    {
243  1 Object[] args = invocation.getArguments();
244   
245  1 WikiPrinter printer = (WikiPrinter) args[1];
246  1 printer.print(renderedContent);
247   
248  1 return null;
249    }
250    }).when(plainRenderer).render((Block) any(), any());
251   
252    // Raw Content
253  1 String rawContent = "raw content";
254  1 when(this.document.getContent()).thenReturn(rawContent);
255   
256    //
257    // Call
258    //
259  1 SolrInputDocument solrDocument = this.mocker.getComponentUnderTest().getSolrDocument(this.documentReference);
260   
261    //
262    // Assert and verify
263    //
264  1 assertEquals(id, solrDocument.getFieldValue(FieldUtils.ID));
265   
266  1 assertEquals(this.documentReference.getWikiReference().getName(), solrDocument.getFieldValue(FieldUtils.WIKI));
267  1 assertEquals(Arrays.asList("Path", "To", "Page"), solrDocument.getFieldValues(FieldUtils.SPACES));
268  1 assertEquals(this.documentReference.getName(), solrDocument.getFieldValue(FieldUtils.NAME));
269   
270  1 assertEquals(Arrays.asList("0/Path.", "1/Path.To.", "2/Path.To.Page."),
271    solrDocument.getFieldValues(FieldUtils.SPACE_FACET));
272  1 assertEquals(Arrays.asList("Path", "Path.To", "Path.To.Page"),
273    solrDocument.getFieldValues(FieldUtils.SPACE_PREFIX));
274   
275  1 assertEquals(Locale.US.toString(), solrDocument.getFieldValue(FieldUtils.LOCALE));
276  1 assertEquals(Locale.US.getLanguage(), solrDocument.getFieldValue(FieldUtils.LANGUAGE));
277  1 Collection<?> actualLocales = solrDocument.getFieldValues(FieldUtils.LOCALES);
278    // The order of the locales in the returned collection is nondeterministic.
279  1 assertTrue(
280    actualLocales.size() == 2 && actualLocales.contains("") && actualLocales.contains(Locale.US.toString()));
281  1 assertEquals(this.document.isHidden(), solrDocument.getFieldValue(FieldUtils.HIDDEN));
282  1 assertEquals(EntityType.DOCUMENT.name(), solrDocument.getFieldValue(FieldUtils.TYPE));
283   
284  1 assertEquals(fullName, solrDocument.getFieldValue(FieldUtils.FULLNAME));
285   
286  1 assertEquals(title, solrDocument.getFieldValue(FieldUtils.getFieldName(FieldUtils.TITLE, Locale.US)));
287  1 assertEquals(rawContent,
288    solrDocument.getFieldValue(FieldUtils.getFieldName(FieldUtils.DOCUMENT_RAW_CONTENT, Locale.US)));
289  1 assertEquals(renderedContent,
290    solrDocument.getFieldValue(FieldUtils.getFieldName(FieldUtils.DOCUMENT_RENDERED_CONTENT, Locale.US)));
291   
292  1 assertEquals(version, solrDocument.getFieldValue(FieldUtils.VERSION));
293  1 assertEquals(comment, solrDocument.getFieldValue(FieldUtils.COMMENT));
294   
295  1 assertEquals(authorStringReference, solrDocument.getFieldValue(FieldUtils.AUTHOR));
296  1 assertEquals(authorDisplayName, solrDocument.getFieldValue(FieldUtils.AUTHOR_DISPLAY));
297  1 assertEquals(creatorStringReference, solrDocument.getFieldValue(FieldUtils.CREATOR));
298  1 assertEquals(creatorDisplayName, solrDocument.getFieldValue(FieldUtils.CREATOR_DISPLAY));
299   
300  1 assertEquals(creationDate, solrDocument.getFieldValue(FieldUtils.CREATIONDATE));
301  1 assertEquals(date, solrDocument.get(FieldUtils.DATE).getValue());
302    }
303   
 
304  1 toggle @Test
305    public void getDocumentThrowingException() throws Exception
306    {
307  1 XWikiException thrown = new XWikiException(XWikiException.MODULE_XWIKI_STORE,
308    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_READING_DOC, "Unreadable document");
309  1 when(this.xcontext.getWiki().getDocument(this.documentReference, this.xcontext)).thenThrow(thrown);
310   
311  1 try {
312  1 this.mocker.getComponentUnderTest().getSolrDocument(this.frenchDocumentReference);
313  0 fail("An exception was expected.");
314    } catch (SolrIndexerException ex) {
315  1 assertEquals("Failed to get input Solr document for entity '" + this.frenchDocumentReference + "'",
316    ex.getMessage());
317  1 assertSame(thrown, ex.getCause());
318    }
319    }
320   
 
321  1 toggle @Test
322    public void getDocumentWithObjects() throws Exception
323    {
324    //
325    // Mock
326    //
327  1 BaseObject comment = mock(BaseObject.class);
328  1 List<BaseProperty<EntityReference>> commentFields = new ArrayList<BaseProperty<EntityReference>>();
329   
330  1 String commentContent = "This is a comment";
331  1 BaseProperty<EntityReference> contentField = mock(BaseProperty.class);
332  1 when(contentField.getName()).thenReturn("comment");
333  1 when(contentField.getValue()).thenReturn(commentContent);
334  1 when(contentField.getObject()).thenReturn(comment);
335  1 commentFields.add(contentField);
336   
337  1 String commentSummary = "summary";
338  1 BaseProperty<EntityReference> summaryField = mock(BaseProperty.class);
339  1 when(summaryField.getName()).thenReturn("summary");
340  1 when(summaryField.getValue()).thenReturn(commentSummary);
341  1 when(summaryField.getObject()).thenReturn(comment);
342  1 commentFields.add(summaryField);
343   
344  1 String commentAuthor = "wiki:space.commentAuthor";
345  1 BaseProperty<EntityReference> authorField = mock(BaseProperty.class);
346  1 when(authorField.getName()).thenReturn("author");
347  1 when(authorField.getValue()).thenReturn(commentAuthor);
348  1 when(authorField.getObject()).thenReturn(comment);
349  1 commentFields.add(authorField);
350   
351  1 Date commentDate = new Date();
352  1 BaseProperty<EntityReference> dateField = mock(BaseProperty.class);
353  1 when(dateField.getName()).thenReturn("date");
354  1 when(dateField.getValue()).thenReturn(commentDate);
355  1 when(dateField.getObject()).thenReturn(comment);
356  1 commentFields.add(dateField);
357   
358    // Adding a fake password field to the comments class just to test the branch in the code.
359  1 String commentPassword = "password";
360  1 BaseProperty<EntityReference> passwordField = mock(BaseProperty.class);
361  1 when(passwordField.getName()).thenReturn("password");
362  1 when(passwordField.getValue()).thenReturn(commentPassword);
363  1 commentFields.add(passwordField);
364   
365  1 List<String> commentList = Arrays.asList("a", "list");
366  1 BaseProperty<EntityReference> listField = mock(BaseProperty.class);
367  1 when(listField.getName()).thenReturn("list");
368  1 when(listField.getValue()).thenReturn(commentList);
369  1 when(listField.getObject()).thenReturn(comment);
370  1 commentFields.add(listField);
371   
372  1 Long commentLikes = 13L;
373  1 BaseProperty<EntityReference> numberField = mock(BaseProperty.class);
374  1 when(numberField.getName()).thenReturn("likes");
375  1 when(numberField.getValue()).thenReturn(commentLikes);
376  1 when(numberField.getObject()).thenReturn(comment);
377  1 commentFields.add(numberField);
378   
379  1 BaseProperty<EntityReference> booleanField = mock(BaseProperty.class);
380  1 when(booleanField.getName()).thenReturn("enabled");
381  1 when(booleanField.getValue()).thenReturn(1);
382  1 when(booleanField.getObject()).thenReturn(comment);
383  1 commentFields.add(booleanField);
384   
385  1 DocumentReference commentsClassReference = new DocumentReference("wiki", "space", "commentsClass");
386  1 when(this.document.getXObjects())
387    .thenReturn(Collections.singletonMap(commentsClassReference, Arrays.asList(comment)));
388   
389  1 EntityReferenceSerializer<String> localEntityReferenceSerializer =
390    this.mocker.getInstance(EntityReferenceSerializer.TYPE_STRING, "local");
391  1 when(localEntityReferenceSerializer.serialize(commentsClassReference)).thenReturn("space.commentsClass");
392   
393  1 BaseClass xclass = mock(BaseClass.class);
394  1 when(comment.getXClass(this.xcontext)).thenReturn(xclass);
395  1 when(comment.getFieldList()).thenReturn(commentFields);
396  1 when(comment.getRelativeXClassReference())
397    .thenReturn(commentsClassReference.removeParent(commentsClassReference.getWikiReference()));
398   
399  1 StringClass stringClass = mock(StringClass.class);
400  1 when(stringClass.getClassType()).thenReturn("String");
401   
402  1 when(xclass.get("comment")).thenReturn(mock(TextAreaClass.class));
403  1 when(xclass.get("summary")).thenReturn(stringClass);
404  1 when(xclass.get("password")).thenReturn(mock(PasswordClass.class));
405  1 when(xclass.get("enabled")).thenReturn(mock(BooleanClass.class));
406   
407    //
408    // Call
409    //
410  1 SolrInputDocument solrDocument =
411    this.mocker.getComponentUnderTest().getSolrDocument(this.frenchDocumentReference);
412   
413    //
414    // Assert and verify
415    //
416  1 assertEquals(Arrays.asList("space.commentsClass"), solrDocument.getFieldValues(FieldUtils.CLASS));
417   
418    // A TextArea property must be indexed as a localized text.
419  1 assertSame(commentContent,
420    solrDocument.getFieldValue(FieldUtils.getFieldName("property.space.commentsClass.comment", Locale.FRENCH)));
421  1 assertNull(solrDocument.getFieldValue("property.space.commentsClass.comment_string"));
422   
423    // A String property must be indexed both as localized text and as raw (unanalyzed) text.
424  1 assertSame(commentSummary,
425    solrDocument.getFieldValue(FieldUtils.getFieldName("property.space.commentsClass.summary", Locale.FRENCH)));
426  1 assertSame(commentSummary, solrDocument.getFieldValue("property.space.commentsClass.summary_string"));
427   
428  1 assertSame(commentAuthor, solrDocument.getFieldValue("property.space.commentsClass.author_string"));
429  1 assertSame(commentDate, solrDocument.getFieldValue("property.space.commentsClass.date_date"));
430  1 assertEquals(commentList, solrDocument.getFieldValues("property.space.commentsClass.list_string"));
431  1 assertSame(commentLikes, solrDocument.getFieldValue("property.space.commentsClass.likes_long"));
432  1 assertTrue((Boolean) solrDocument.getFieldValue("property.space.commentsClass.enabled_boolean"));
433   
434    // Make sure the password is not indexed (neither as a string nor as a localized text).
435  1 assertNull(solrDocument.getFieldValue("property.space.commentsClass.password_string"));
436  1 assertNull(solrDocument
437    .getFieldValue(FieldUtils.getFieldName("property.space.commentsClass.password", Locale.FRENCH)));
438   
439    // Check the sort fields.
440  1 assertSame(commentAuthor, solrDocument.getFieldValue("property.space.commentsClass.author_sortString"));
441  1 assertSame(commentDate, solrDocument.getFieldValue("property.space.commentsClass.date_sortDate"));
442    // The last value is used for sorting because we cannot sort on fields with multiple values.
443  1 assertEquals("list", solrDocument.getFieldValue("property.space.commentsClass.list_sortString"));
444  1 assertSame(commentLikes, solrDocument.getFieldValue("property.space.commentsClass.likes_sortLong"));
445  1 assertTrue((Boolean) solrDocument.getFieldValue("property.space.commentsClass.enabled_sortBoolean"));
446   
447    // Localized texts are sorted as strings if they are not too large.
448  1 assertSame(commentContent, solrDocument.getFieldValue("property.space.commentsClass.comment_sortString"));
449   
450  1 Collection<Object> objectProperties =
451    solrDocument.getFieldValues(FieldUtils.getFieldName("object.space.commentsClass", Locale.FRENCH));
452  1 MatcherAssert.assertThat(objectProperties, Matchers.<Object>containsInAnyOrder(commentContent, commentSummary,
453    commentAuthor, commentDate, commentList.get(0), commentList.get(1), commentLikes, true));
454  1 assertEquals(8, objectProperties.size());
455   
456  1 objectProperties =
457    solrDocument.getFieldValues(FieldUtils.getFieldName(FieldUtils.OBJECT_CONTENT, Locale.FRENCH));
458  1 MatcherAssert.assertThat(objectProperties,
459    Matchers.<Object>containsInAnyOrder("comment : " + commentContent, "summary : " + commentSummary,
460    "author : " + commentAuthor, "date : " + commentDate, "list : " + commentList.get(0),
461    "list : " + commentList.get(1), "likes : " + commentLikes, "enabled : true"));
462  1 assertEquals(8, objectProperties.size());
463    }
464   
465    /**
466    * @see "XWIKI-9417: Search does not return any results for Static List values"
467    */
 
468  1 toggle @Test
469    public void setStaticListPropertyValue() throws Exception
470    {
471  1 BaseObject xobject = mock(BaseObject.class);
472   
473  1 @SuppressWarnings("unchecked")
474    BaseProperty<EntityReference> listProperty = mock(BaseProperty.class);
475  1 when(listProperty.getName()).thenReturn("color");
476  1 when(listProperty.getValue()).thenReturn(Arrays.asList("red", "green"));
477  1 when(listProperty.getObject()).thenReturn(xobject);
478   
479  1 DocumentReference classReference = new DocumentReference("wiki", "Space", "MyClass");
480  1 when(this.document.getXObjects()).thenReturn(Collections.singletonMap(classReference, Arrays.asList(xobject)));
481   
482  1 BaseClass xclass = mock(BaseClass.class);
483  1 when(xobject.getXClass(this.xcontext)).thenReturn(xclass);
484  1 when(xobject.getFieldList()).thenReturn(Arrays.<Object>asList(listProperty));
485  1 when(xobject.getRelativeXClassReference())
486    .thenReturn(classReference.removeParent(classReference.getWikiReference()));
487   
488  1 StaticListClass staticListClass = mock(StaticListClass.class);
489  1 when(xclass.get("color")).thenReturn(staticListClass);
490  1 when(staticListClass.getMap(xcontext))
491    .thenReturn(Collections.singletonMap("red", new ListItem("red", "Dark Red")));
492   
493  1 SolrInputDocument solrDocument = this.mocker.getComponentUnderTest().getSolrDocument(this.documentReference);
494   
495    // Make sure both the raw value (which is saved in the database) and the display value (specified in the XClass)
496    // are indexed. The raw values are indexed as strings in order to be able to perform exact matches.
497  1 assertEquals(Arrays.asList("red", "green"), solrDocument.getFieldValues("property.Space.MyClass.color_string"));
498  1 assertEquals(Collections.singletonList("Dark Red"),
499    solrDocument.getFieldValues(FieldUtils.getFieldName("property.Space.MyClass.color", Locale.US)));
500   
501    // Check the sort field. Only the last value we set is used for sorting because we cannot sort on fields that
502    // have multiple values.
503  1 assertEquals(Collections.singletonList("green"),
504    solrDocument.getFieldValues("property.Space.MyClass.color_sortString"));
505    }
506   
 
507  2 toggle private XWikiAttachment createMockAttachment(String fileName, String mimeType, Date date, String content,
508    String authorAlias, String authorDisplayName) throws Exception
509    {
510  2 return createMockAttachment(fileName, mimeType, date, content.getBytes(), authorAlias, authorDisplayName);
511    }
512   
 
513  8 toggle private XWikiAttachment createMockAttachment(String fileName, String mimeType, Date date, InputStream content,
514    String authorAlias, String authorDisplayName) throws Exception
515    {
516  8 return createMockAttachment(fileName, mimeType, date, IOUtils.toByteArray(content), authorAlias,
517    authorDisplayName);
518    }
519   
 
520  10 toggle private XWikiAttachment createMockAttachment(String fileName, String mimeType, Date date, byte[] content,
521    String authorAlias, String authorDisplayName) throws Exception
522    {
523  10 XWikiAttachment attachment = mock(XWikiAttachment.class, fileName);
524  10 when(attachment.getReference()).thenReturn(new AttachmentReference(fileName, this.documentReference));
525  10 when(attachment.getFilename()).thenReturn(fileName);
526  10 when(attachment.getMimeType(this.xcontext)).thenReturn(mimeType);
527  10 when(attachment.getDate()).thenReturn(date);
528  10 when(attachment.getLongSize()).thenReturn((long)content.length);
529  10 when(attachment.getContentInputStream(this.xcontext)).thenReturn(new ByteArrayInputStream(content));
530   
531  10 String authorFullName = "XWiki." + authorAlias;
532  10 DocumentReference authorReference = new DocumentReference("wiki", "XWiki", authorAlias);
533  10 when(attachment.getAuthorReference()).thenReturn(authorReference);
534   
535  10 EntityReferenceSerializer<String> serializer = this.mocker.getInstance(EntityReferenceSerializer.TYPE_STRING);
536  10 String authorStringReference = "wiki:" + authorFullName;
537  10 when(serializer.serialize(authorReference)).thenReturn(authorStringReference);
538   
539  10 when(this.xcontext.getWiki().getPlainUserName(authorReference, this.xcontext)).thenReturn(authorDisplayName);
540   
541  10 return attachment;
542    }
543   
544    // Attachments
545   
 
546  8 toggle private void assertAttachmentExtract(String expect, String filename) throws Exception
547    {
548  8 XWikiAttachment logo;
549  8 try (InputStream stream = getClass().getResourceAsStream("/files/" + filename)) {
550  8 logo = createMockAttachment(filename, "image/png", new Date(), stream, "Alice", "Shy Alice");
551  8 when(this.document.getAttachmentList()).thenReturn(Arrays.<XWikiAttachment>asList(logo));
552    }
553   
554  8 SolrInputDocument solrDocument = this.mocker.getComponentUnderTest().getSolrDocument(this.documentReference);
555   
556  8 assertEquals("Wrong attachment content indexed", expect, solrDocument.getFieldValue("attcontent_en_US"));
557   
558    }
559   
 
560  1 toggle @Test
561    public void getDocumentWithAttachments() throws Exception
562    {
563  1 Date logoDate = new Date(123);
564  1 XWikiAttachment logo = createMockAttachment("logo.png", "image/png", logoDate, "foo", "Alice", "Shy Alice");
565  1 Date todoDate = new Date(456);
566  1 XWikiAttachment todo = createMockAttachment("todo.txt", "text/plain", todoDate, "bar bar", "Bob", "Angry Bob");
567  1 when(this.document.getAttachmentList()).thenReturn(Arrays.<XWikiAttachment>asList(logo, todo));
568   
569  1 SolrInputDocument solrDocument =
570    this.mocker.getComponentUnderTest().getSolrDocument(this.frenchDocumentReference);
571   
572  1 assertEquals(Arrays.asList("logo.png", "todo.txt"), solrDocument.getFieldValues(FieldUtils.FILENAME));
573  1 assertEquals(Arrays.asList("image/png", "text/plain"), solrDocument.getFieldValues(FieldUtils.MIME_TYPE));
574  1 assertEquals(Arrays.asList(logoDate, todoDate), solrDocument.getFieldValues(FieldUtils.ATTACHMENT_DATE));
575  1 assertEquals(Arrays.asList(3L, 7L), solrDocument.getFieldValues(FieldUtils.ATTACHMENT_SIZE));
576  1 assertEquals(Arrays.asList("foo\n", "bar bar\n"), solrDocument.getFieldValues("attcontent_fr"));
577  1 assertEquals(Arrays.asList("wiki:XWiki.Alice", "wiki:XWiki.Bob"),
578    solrDocument.getFieldValues(FieldUtils.ATTACHMENT_AUTHOR));
579  1 assertEquals(Arrays.asList("Shy Alice", "Angry Bob"),
580    solrDocument.getFieldValues(FieldUtils.ATTACHMENT_AUTHOR_DISPLAY));
581    }
582   
 
583  1 toggle @Test
584    public void testAttachmentExtractFromTxt() throws Exception
585    {
586  1 assertAttachmentExtract("text content\n", "txt.txt");
587    }
588   
 
589  1 toggle @Test
590    public void testAttachmentExtractFromMSOffice97() throws Exception
591    {
592  1 assertAttachmentExtract("MS Office 97 content\n\n", "msoffice97.doc");
593   
594    }
595   
 
596  1 toggle @Test
597    public void testAttachmentExtractFromOpenXML() throws Exception
598    {
599  1 assertAttachmentExtract("OpenXML content\n", "openxml.docx");
600    }
601   
 
602  1 toggle @Test
603    public void testAttachmentExtractFromOpenDocument() throws Exception
604    {
605  1 assertAttachmentExtract("OpenDocument content\n", "opendocument.odt");
606    }
607   
 
608  1 toggle @Test
609    public void testAttachmentExtractFromPDF() throws Exception
610    {
611  1 assertAttachmentExtract("\nPDF content\n\n\n", "pdf.pdf");
612    }
613   
 
614  1 toggle @Test
615    public void testAttachmentExtractFromZIP() throws Exception
616    {
617  1 assertAttachmentExtract("\nzip.txt\nzip content\n\n\n\n", "zip.zip");
618    }
619   
 
620  1 toggle @Test
621    public void testAttachmentExtractFromHTML() throws Exception
622    {
623  1 assertAttachmentExtract("something\n", "html.html");
624    }
625   
 
626  1 toggle @Test
627    public void testAttachmentExtractFromClass() throws Exception
628    {
629  1 String expectedContent =
630    "public synchronized class HelloWorld {\n" +
631    " public void HelloWorld();\n" +
632    " public static void main(String[]);\n" +
633    "}\n\n";
634  1 assertAttachmentExtract(expectedContent, "HelloWorld.class");
635    }
636    }