Skip to content

Commit

Permalink
Merge branch 'master' of github.com:xwiki/xwiki-platform into XWIKI-2…
Browse files Browse the repository at this point in the history
…1763
  • Loading branch information
mflorea committed Feb 9, 2024
2 parents 86c0c57 + 5e10fb9 commit 3f207f8
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@

Content of first section.

[[image:attach:xwiki-logo.png||width="100"]]</content>
[[image:attach:xwiki-logo.png||width="100"]]

[[image:attach:xwiki-logo.png||width="100" class="force-server-side-resize"]]

{{velocity}}
{{html}}
&lt;img src="$doc.getAttachmentURL('xwiki-logo.png', 'download', 'height=50')" alt="XWiki Logo" /&gt;
{{/html}}
{{/velocity}}</content>
<attachment>
<filename>xwiki-logo.png</filename>
<mimetype>image/png</mimetype>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,20 @@ void exportAsPDF(TestUtils setup, TestConfiguration testConfiguration) throws Ex
assertTrue(contentPageText.contains("Child\nSection 1\nContent of first section.\n"),
"Child document content missing: " + contentPageText);

// The content of the child document shows an image.
// The content of the child document shows the same image multiple times.
List<PDFImage> contentPageImages = pdf.getImagesFromPage(3);
assertEquals(1, contentPageImages.size());
assertEquals(3, contentPageImages.size());

// Verify the image included in the PDF is not resized server-side (we know the image width is specified in
// the source wiki syntax and we enabled the server-side image resize by default).
// Verify the images included in the PDF are not resized server-side (we know the image width is specified
// in the source wiki syntax and we enabled the server-side image resize by default).
assertEquals(512, contentPageImages.get(0).getRawWidth());
assertEquals(512, contentPageImages.get(0).getRawHeight());
assertEquals(512, contentPageImages.get(2).getRawWidth());
assertEquals(512, contentPageImages.get(2).getRawHeight());

// For the second image we force the server-side resize.
assertEquals(100, contentPageImages.get(1).getRawWidth());
assertEquals(100, contentPageImages.get(1).getRawHeight());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,38 @@ require([
}).wrap("&lt;span&gt;&lt;/span&gt;");
};

/**
* Removes the image size (width and height) from the image URL query string in order to prevent the server-side
* resize of the image, thus allowing the full size image to be included in the generated PDF.
*/
async function disableServerSideImageResize() {
const imageLoadPromises = []
document.querySelectorAll('#xwikicontent img:not(.force-server-side-resize)').forEach(image =&gt; {
const imageURL = new URL(image.src);
const imageParams = imageURL.searchParams;
if (imageParams.has('width') || imageParams.has('height')) {
// Backup the original query string before we modify the image URL.
const oldImageQueryString = imageURL.search;
// The image size is specified in the URL which may trigger a server-side resize. We want the full image to be
// included in the PDF so let's remove these parameters.
imageParams.delete('width');
imageParams.delete('height');
const newImageQueryString = '?' + imageParams.toString();
const newImageSrc = image.getAttribute('src').replace(oldImageQueryString, newImageQueryString);
// Create a promise for when the full size image is loaded.
imageLoadPromises.push(new Promise((resolve, reject) =&gt; {
image.addEventListener('load', resolve);
image.addEventListener('error', reject);
image.addEventListener('abort', resolve);
image.setAttribute('src', newImageSrc);
}));
}
});
await Promise.allSettled(imageLoadPromises);
}

pageReady.delayPageReady(disableServerSideImageResize(), 'Disable server-side image resize.');

// Adjust the exported content before performing the print layout.
pageReady.afterPageReady(() =&gt; {
refactorAnchors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ XWiki.PDFExport.ConfigurationClass_maxContentSize.hint=단일 PDF 내보내기
XWiki.PDFExport.ConfigurationClass_replaceFOP=FOP 교체
XWiki.PDFExport.ConfigurationClass_replaceFOP.hint=Apache Formatting Objects Processor(FOP)를 기반으로 이전 PDF 내보내기를 대체합니다.
</content>
</xwikidoc>
</xwikidoc>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<properties>
<!-- Name to display by the Extension Manager -->
<xwiki.extension.name>Font Awesome Icon Theme</xwiki.extension.name>
<!-- Category to display in the Extension Manager -->
<xwiki.extension.category>icontheme</xwiki.extension.category>
<!-- Old names of this module used for retro compatibility when resolving dependencies of old extensions -->
<xwiki.extension.features>
<!-- only used in 6.2M1 -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@

import java.net.URL;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.test.mockito.MockitoComponentMockingRule;
import org.xwiki.test.junit5.mockito.ComponentTest;
import org.xwiki.test.junit5.mockito.InjectMockComponents;
import org.xwiki.test.junit5.mockito.MockComponent;
import org.xwiki.url.ExtendedURL;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.descriptor.WikiDescriptorManager;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

/**
Expand All @@ -41,78 +42,81 @@
* @version $Id$
* @since 6.3M1
*/
public class PathWikiReferenceExtractorTest
@ComponentTest
class PathWikiReferenceExtractorTest
{
@Rule
public MockitoComponentMockingRule<PathWikiReferenceExtractor> mocker =
new MockitoComponentMockingRule<>(PathWikiReferenceExtractor.class);
@InjectMockComponents
private PathWikiReferenceExtractor extractor;

@MockComponent
private WikiDescriptorManager wikiDescriptorManager;

@Before
public void setUp() throws Exception
@MockComponent
private Execution execution;

@MockComponent
private StandardURLConfiguration urlConfiguration;

@BeforeEach
void setUp() throws Exception
{
this.wikiDescriptorManager = mocker.getInstance(WikiDescriptorManager.class);
when(wikiDescriptorManager.getMainWikiId()).thenReturn("xwiki");
when(this.wikiDescriptorManager.getMainWikiId()).thenReturn("xwiki");
}

@Test
public void extractWhenWikiDescriptor() throws Exception
void extractWhenWikiDescriptor() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.REDIRECT_TO_MAIN_WIKI);

WikiDescriptorManager wikiDescriptorManager = mocker.getInstance(WikiDescriptorManager.class);
when(wikiDescriptorManager.getByAlias("someWiki")).thenReturn(new WikiDescriptor("wikiid", "someWiki"));
when(this.wikiDescriptorManager.getByAlias("someWiki")).thenReturn(new WikiDescriptor("wikiid", "someWiki"));

testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "wikiid");
}

@Test
public void extractWhenNoWikiDescriptor() throws Exception
void extractWhenNoWikiDescriptor() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.REDIRECT_TO_MAIN_WIKI);
testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "xwiki");
}

@Test
public void extractWhenWikiDescriptorButEmptyServerName() throws Exception
void extractWhenWikiDescriptorButEmptyServerName() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.REDIRECT_TO_MAIN_WIKI);

WikiDescriptorManager wikiDescriptorManager = mocker.getInstance(WikiDescriptorManager.class);
when(wikiDescriptorManager.getByAlias("someWiki")).thenReturn(new WikiDescriptor("", "someWiki"));
when(this.wikiDescriptorManager.getByAlias("someWiki")).thenReturn(new WikiDescriptor("", "someWiki"));

testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "xwiki");
}

@Test
public void extractWhenNoDescriptorMatchingAliasButDescriptorMatchingId() throws Exception
void extractWhenNoDescriptorMatchingAliasButDescriptorMatchingId() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.REDIRECT_TO_MAIN_WIKI);

WikiDescriptorManager wikiDescriptorManager = mocker.getInstance(WikiDescriptorManager.class);
when(wikiDescriptorManager.getByAlias("someWiki")).thenReturn(null);
when(wikiDescriptorManager.getById("someWiki")).thenReturn(new WikiDescriptor("dummy", "dummy"));
when(this.wikiDescriptorManager.getByAlias("someWiki")).thenReturn(null);
when(this.wikiDescriptorManager.getById("someWiki")).thenReturn(new WikiDescriptor("dummy", "dummy"));

testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "somewiki");
}

@Test
public void extractWhenNoWikiDescriptorButWithDomainBasedURL() throws Exception
void extractWhenNoWikiDescriptorButWithDomainBasedURL() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.REDIRECT_TO_MAIN_WIKI);
testAndAssert("http://wiki.server.com/xwiki/bin/view/Main/WebHome", "xwiki");
}

@Test
public void extractWhenNoWikiDescriptorAndDisplayErrorWhenWikiNotFound() throws Exception
void extractWhenNoWikiDescriptorAndDisplayErrorWhenWikiNotFound() throws Exception
{
setUpConfiguration(WikiNotFoundBehavior.DISPLAY_ERROR);
testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "somewiki");
}

@Test
public void extractWhenNoExecutionContext() throws Exception
void extractWhenNoExecutionContext() throws Exception
{
testAndAssert("http://localhost/xwiki/wiki/someWiki/view/Main/WebHome", "somewiki");

Expand All @@ -125,19 +129,16 @@ private void testAndAssert(String urlToTest, String expectedWikiId) throws Excep
ExtendedURL url = new ExtendedURL(new URL(urlToTest), "xwiki");
// Remove the resource type (i.e. the first segment) since this is what is expected by the extractor
url.getSegments().remove(0);
WikiReference wikiReference = this.mocker.getComponentUnderTest().extract(url);
WikiReference wikiReference = this.extractor.extract(url);
assertEquals(new WikiReference(expectedWikiId), wikiReference);
}

private void setUpConfiguration(WikiNotFoundBehavior wikiNotFoundBehavior) throws Exception
private void setUpConfiguration(WikiNotFoundBehavior wikiNotFoundBehavior)
{
// Simulate a configured Execution Context
Execution execution = mocker.getInstance(Execution.class);
ExecutionContext executionContext = new ExecutionContext();
executionContext.setProperty("xwikicontext", true);
when(execution.getContext()).thenReturn(executionContext);

StandardURLConfiguration urlConfiguration = mocker.getInstance(StandardURLConfiguration.class);
when(urlConfiguration.getWikiNotFoundBehavior()).thenReturn(wikiNotFoundBehavior);
when(this.execution.getContext()).thenReturn(executionContext);
when(this.urlConfiguration.getWikiNotFoundBehavior()).thenReturn(wikiNotFoundBehavior);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@
*/
package org.xwiki.url.internal.standard;

import org.junit.Rule;
import org.junit.Test;
import javax.inject.Named;

import org.junit.jupiter.api.Test;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.component.util.DefaultParameterizedType;
import org.xwiki.resource.AbstractResourceReference;
import org.xwiki.resource.ResourceReferenceSerializer;
import org.xwiki.resource.ResourceType;
import org.xwiki.resource.UnsupportedResourceReferenceException;
import org.xwiki.test.mockito.MockitoComponentMockingRule;
import org.xwiki.test.junit5.mockito.ComponentTest;
import org.xwiki.test.junit5.mockito.InjectMockComponents;
import org.xwiki.test.junit5.mockito.MockComponent;
import org.xwiki.url.ExtendedURL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;

/**
Expand All @@ -41,11 +44,15 @@
* @version $Id$
* @since 6.1M2
*/
public class StandardExtendedURLResourceReferenceSerializerTest
@ComponentTest
class StandardExtendedURLResourceReferenceSerializerTest
{
@Rule
public MockitoComponentMockingRule<StandardExtendedURLResourceReferenceSerializer> mocker =
new MockitoComponentMockingRule<>(StandardExtendedURLResourceReferenceSerializer.class);
@InjectMockComponents
private StandardExtendedURLResourceReferenceSerializer serializer;

@MockComponent
@Named("context")
private ComponentManager componentManager;

public class TestResourceReference extends AbstractResourceReference
{
Expand All @@ -56,41 +63,37 @@ public TestResourceReference()
}

@Test
public void serialize() throws Exception
void serialize() throws Exception
{
TestResourceReference resource = new TestResourceReference();

ResourceReferenceSerializer serializer = mock(ResourceReferenceSerializer.class);

ComponentManager componentManager = this.mocker.getInstance(ComponentManager.class, "context");
when(componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
when(this.componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
TestResourceReference.class, ExtendedURL.class), "standard")).thenReturn(serializer);

this.mocker.getComponentUnderTest().serialize(resource);
this.serializer.serialize(resource);

// Verify the serializer is called and with the proper parameters
verify(serializer).serialize(same(resource));
}

@Test
public void serializeWhenNoMatchingSerializer() throws Exception
void serializeWhenNoMatchingSerializer() throws Exception
{
TestResourceReference resource = new TestResourceReference();

ComponentManager componentManager = this.mocker.getInstance(ComponentManager.class, "context");
when(componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
when(this.componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
TestResourceReference.class, ExtendedURL.class), "standard")).thenThrow(
new ComponentLookupException("error"));
when(componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
when(this.componentManager.getInstance(new DefaultParameterizedType(null, ResourceReferenceSerializer.class,
TestResourceReference.class, ExtendedURL.class))).thenThrow(
new ComponentLookupException("error"));

try {
this.mocker.getComponentUnderTest().serialize(resource);
fail("Should have thrown an exception here");
} catch (UnsupportedResourceReferenceException expected) {
assertEquals("Failed to find serializer for Resource Reference [type = [test], parameters = []] and "
+ "URL format [standard]", expected.getMessage());
}
Throwable exception = assertThrows(UnsupportedResourceReferenceException.class, () -> {
this.serializer.serialize(resource);
});
assertEquals("Failed to find serializer for Resource Reference [type = [test], parameters = []] and "
+ "URL format [standard]", exception.getMessage());
}
}

0 comments on commit 3f207f8

Please sign in to comment.