PageRenderTime 33ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/atlassian-plugins-webresource/src/test/java/com/atlassian/plugin/webresource/impl/support/factory/InitialMinifiedContentBuilderTest.java

https://bitbucket.org/atlassian/atlassian-plugins-webresource
Java | 331 lines | 233 code | 25 blank | 73 comment | 3 complexity | cd1039c854fa5c9d8ee1fd554e31e9cc MD5 | raw file
  1. package com.atlassian.plugin.webresource.impl.support.factory;
  2. import com.atlassian.plugin.webresource.impl.Globals;
  3. import com.atlassian.plugin.webresource.impl.config.Config;
  4. import com.atlassian.plugin.webresource.impl.http.Router;
  5. import com.atlassian.plugin.webresource.impl.snapshot.Bundle;
  6. import com.atlassian.plugin.webresource.impl.snapshot.resource.Resource;
  7. import com.atlassian.plugin.webresource.impl.support.InitialContent;
  8. import com.atlassian.sourcemap.ReadableSourceMap;
  9. import com.atlassian.sourcemap.ReadableSourceMapImpl;
  10. import com.atlassian.webresource.spi.ResourceCompiler;
  11. import org.junit.Before;
  12. import org.junit.Test;
  13. import org.junit.runner.RunWith;
  14. import org.mockito.Mock;
  15. import org.mockito.Spy;
  16. import org.mockito.junit.MockitoJUnitRunner;
  17. import static com.atlassian.plugin.webresource.impl.config.Config.JS_TYPE;
  18. import static com.atlassian.plugin.webresource.mocks.MockBuilder.builder;
  19. import static com.atlassian.sourcemap.ReadableSourceMap.toWritableSourceMap;
  20. import static com.atlassian.sourcemap.ReadableSourceMapImpl.fromSource;
  21. import static java.util.Objects.nonNull;
  22. import static java.util.Optional.of;
  23. import static org.junit.Assert.assertEquals;
  24. import static org.junit.Assert.assertTrue;
  25. import static org.mockito.Mockito.mock;
  26. import static org.mockito.Mockito.never;
  27. import static org.mockito.Mockito.verify;
  28. import static org.mockito.Mockito.when;
  29. @RunWith(MockitoJUnitRunner.Silent.class)
  30. public class InitialMinifiedContentBuilderTest {
  31. private static final String JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME = "/x/y/z.min.js";
  32. private static final String JAVASCRIPT_FILE_NAME = "/x/y/z.js";
  33. private static final String JAVASCRIPT_MINIFIED_INPUT = "var test='Hello World';console.log(test);";
  34. private static final String JAVASCRIPT_MINIFIED_FILE_MAP_NAME = "/x/y/z.min.js.map";
  35. private static final String JAVASCRIPT_MINIFIED_FILE_MAP_OUTPUT = "{ version : 3, file: '/x/y/z.js', sourceRoot : '', sources: ['/x/y/z.js'], names: ['statement', 'window.console.log'], mappings: 'AAgBC,SAAQ,CAAEA' }";
  36. private static final String JAVASCRIPT_MINIFIED_FILE_NAME = "/x/y/z-min.js";
  37. @Mock
  38. private Bundle bundle;
  39. @Mock
  40. private Globals globals;
  41. @Mock
  42. private Config config;
  43. @Mock
  44. private Router router;
  45. @Mock
  46. private Resource resource;
  47. @Mock
  48. private ResourceCompiler resourceCompiler;
  49. @Spy
  50. private final InitialSourceContentBuilder initialSourceContentBuilder = new InitialSourceContentBuilder();
  51. private InitialMinifiedContentBuilder underTest;
  52. @Before
  53. public void setUp() {
  54. builder().withMockedGlobals(globals)
  55. .router(router)
  56. .config(config);
  57. underTest = new InitialMinifiedContentBuilder(globals, initialSourceContentBuilder);
  58. }
  59. /**
  60. * WHEN resource = /x/y/z.js
  61. * AND global minification is enabled
  62. * THEN return resource minified version.
  63. */
  64. @Test
  65. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsEnabled_Then_ReturnMinifiedContent() {
  66. final Callable mocker = () -> builder().withMockedConfig(config)
  67. .minificationEnabled(true)
  68. .globalMinificationEnabled(true)
  69. .withMockedResourceCompiler(resourceCompiler)
  70. .content(JAVASCRIPT_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT)
  71. .done()
  72. .and()
  73. .withMockedBundle(bundle)
  74. .minificationEnabled(true)
  75. .and()
  76. .withMockedResource(resource)
  77. .parent(bundle)
  78. .nameOrLocationType(JS_TYPE)
  79. .path(JAVASCRIPT_FILE_NAME);
  80. testContent(mocker, null);
  81. }
  82. /**
  83. * WHEN resource = /x/y/z.js
  84. * AND global minification is not enabled
  85. * AND there is file for minified path. E.g: /x/y/z-min.js
  86. * THEN return resource minified version.
  87. */
  88. @Test
  89. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsMinifiedVersionForMinifiedPath_Then_ReturnMinifiedContent() {
  90. final Callable mocker = () -> builder().withMockedConfig(config)
  91. .minificationEnabled(true)
  92. .and()
  93. .withMockedBundle(bundle)
  94. .minificationEnabled(true)
  95. .and()
  96. .withMockedResource(resource)
  97. .parent(bundle)
  98. .path(JAVASCRIPT_FILE_NAME)
  99. .streamFor(JAVASCRIPT_MINIFIED_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT);
  100. testContent(mocker, null);
  101. }
  102. /**
  103. * WHEN resource = /x/y/z.js
  104. * AND global minification is not enabled
  105. * AND there is file for alternate minified path. E.g: /x/y/z.min.js
  106. * THEN return resource minified version.
  107. */
  108. @Test
  109. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsMinifiedVersionForAlternateMinifiedPath_Then_ReturnMinifiedContent() {
  110. final Callable mocker = () -> builder().withMockedConfig(config)
  111. .minificationEnabled(true)
  112. .and()
  113. .withMockedBundle(bundle)
  114. .minificationEnabled(true)
  115. .and()
  116. .withMockedResource(resource)
  117. .parent(bundle)
  118. .path(JAVASCRIPT_FILE_NAME)
  119. .streamFor(JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT);
  120. testContent(mocker, null);
  121. }
  122. /**
  123. * WHEN resource = /x/y/z.js
  124. * AND global minification is enabled
  125. * THEN return minified path. E.g: /x/y/z-min.js
  126. */
  127. @Test
  128. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsEnabled_Then_ReturnMinifiedPath() {
  129. final Callable mocker = () -> builder().withMockedConfig(config)
  130. .minificationEnabled(true)
  131. .globalMinificationEnabled(true)
  132. .withMockedResourceCompiler(resourceCompiler)
  133. .content(JAVASCRIPT_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT)
  134. .done()
  135. .and()
  136. .withMockedBundle(bundle)
  137. .minificationEnabled(true)
  138. .and()
  139. .withMockedResource(resource)
  140. .parent(bundle)
  141. .nameOrLocationType(JS_TYPE)
  142. .path(JAVASCRIPT_FILE_NAME);
  143. testPath(mocker, JAVASCRIPT_MINIFIED_FILE_NAME);
  144. }
  145. /**
  146. * WHEN resource = /x/y/z.js
  147. * AND global minification is not enabled
  148. * AND there is file for minified path. E.g: /x/y/z-min.js
  149. * THEN return minified path. E.g: /x/y/z-min.js
  150. */
  151. @Test
  152. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsMinifiedVersionForMinifiedPath_Then_ReturnMinifiedPath() {
  153. final Callable mocker = () -> builder().withMockedConfig(config)
  154. .minificationEnabled(true)
  155. .and()
  156. .withMockedBundle(bundle)
  157. .minificationEnabled(true)
  158. .and()
  159. .withMockedResource(resource)
  160. .parent(bundle)
  161. .path(JAVASCRIPT_FILE_NAME)
  162. .streamFor(JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT);
  163. testPath(mocker, JAVASCRIPT_MINIFIED_FILE_NAME);
  164. }
  165. /**
  166. * WHEN resource = /x/y/z.js
  167. * AND global minification is not enabled
  168. * AND there is file for alternate minified path. E.g: /x/y/z.min.js
  169. * THEN return minified path. E.g: /x/y/z-min.js
  170. */
  171. @Test
  172. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsMinifiedVersionForAlternateMinifiedPath_Then_ReturnMinifiedPath() {
  173. final Callable mocker = () -> builder().withMockedConfig(config)
  174. .minificationEnabled(true)
  175. .and()
  176. .withMockedBundle(bundle)
  177. .minificationEnabled(true)
  178. .and()
  179. .withMockedResource(resource)
  180. .parent(bundle)
  181. .path(JAVASCRIPT_FILE_NAME)
  182. .streamFor(JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT);
  183. testPath(mocker, JAVASCRIPT_MINIFIED_FILE_NAME);
  184. }
  185. /**
  186. * WHEN resource = /x/y/z.js
  187. * AND global minification is not enabled
  188. * AND there is not any minified version.
  189. * THEN return minified path. E.g: /x/y/z-min.js
  190. */
  191. @Test
  192. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsNotAnyMinifiedVersion_Then_ReturnAlternateMinifiedPath() {
  193. final Callable mocker = () -> builder().withMockedConfig(config)
  194. .minificationEnabled(true)
  195. .and()
  196. .withMockedBundle(bundle)
  197. .minificationEnabled(true)
  198. .and()
  199. .withMockedResource(resource)
  200. .parent(bundle)
  201. .path(JAVASCRIPT_FILE_NAME);
  202. testPath(mocker, JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME);
  203. }
  204. @Test
  205. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsNotAnyPreBuildSource_Then_ReturnSourceMapForRawContent() {
  206. //given
  207. final InitialContent mockedInitialContent = mock(InitialContent.class);
  208. when(mockedInitialContent.getPath()).thenReturn(of(JAVASCRIPT_FILE_NAME));
  209. when(initialSourceContentBuilder.build()).thenReturn(mockedInitialContent);
  210. builder().withMockedConfig(config)
  211. .minificationEnabled(true)
  212. .and()
  213. .withMockedBundle(bundle)
  214. .minificationEnabled(true)
  215. .and()
  216. .withMockedResource(resource)
  217. .parent(bundle)
  218. .path(JAVASCRIPT_FILE_NAME)
  219. .streamFor(JAVASCRIPT_MINIFIED_FILE_MAP_NAME, JAVASCRIPT_MINIFIED_FILE_MAP_OUTPUT);
  220. //when
  221. final InitialContent actualInitialContent = underTest.withPath(resource)
  222. .withSourceMap(resource)
  223. .build();
  224. //then
  225. final String expectedSourceMapRawContent = "{ version : 3, file: '/x/y/z.js', sourceRoot : '', sources: ['/x/y/z.js'], names: ['statement', 'window.console.log'], mappings: 'AAgBC,SAAQ,CAAEA' }";
  226. final ReadableSourceMap expectedSourceMap = fromSource(expectedSourceMapRawContent);
  227. assertTrue(actualInitialContent.getSourceMap().isPresent());
  228. actualInitialContent.getSourceMap()
  229. .ifPresent(actualSourceMap -> assertEquals(toWritableSourceMap(expectedSourceMap).generateForHumans(), toWritableSourceMap(actualSourceMap).generateForHumans()));
  230. }
  231. /**
  232. * WHEN resource = /x/y/z.js
  233. * AND global minification is not enabled
  234. * AND there is minified version for minified path. E.g: /x/y/z-min.js
  235. * AND there is minified version generated by resource compiler.
  236. * THEN opt for minified content.
  237. */
  238. @Test
  239. public void when_JavaScriptFileIsNotMinified_And_GlobalMinificationIsNotEnabled_And_ThereIsMinifiedVersionForMinifiedPath_And_ThereIsFileGeneratedByResourceCompiler_Then_OptForMinifiedContent() {
  240. final Callable mocker = () -> builder().withMockedConfig(config)
  241. .minificationEnabled(true)
  242. .and()
  243. .withMockedBundle(bundle)
  244. .minificationEnabled(true)
  245. .and()
  246. .withMockedResource(resource)
  247. .parent(bundle)
  248. .path(JAVASCRIPT_FILE_NAME)
  249. .streamFor(JAVASCRIPT_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT)
  250. .streamFor(JAVASCRIPT_MINIFIED_FILE_NAME, JAVASCRIPT_MINIFIED_INPUT);
  251. final Callable verifier = () -> {
  252. verify(resourceCompiler, never()).content(resource.getPath());
  253. verify(resource, never()).getStreamFor(JAVASCRIPT_ALTERNATE_MINIFIED_FILE_NAME);
  254. };
  255. testContent(mocker, verifier);
  256. }
  257. /**
  258. * Executes a certain test and verify if the actual content is equals to the expected one.
  259. * @param mocker The {@link Callable} responsible for performing the mocking.
  260. * @param verifier The {@link Callable} responsible for performing extra verifications.
  261. */
  262. private void testContent(final Callable mocker, final Callable verifier) {
  263. //given
  264. if(nonNull(mocker)) {
  265. mocker.call();
  266. }
  267. //when
  268. final InitialMinifiedContentBuilder actualInitialContentBuilder = underTest.withContent(resource);
  269. final InitialContentTest actualInitialContent = new InitialContentTest(actualInitialContentBuilder.build());
  270. //then
  271. assertTrue(actualInitialContent.getContentAsString().isPresent());
  272. actualInitialContent
  273. .getContentAsString()
  274. .ifPresent(actualContent -> assertEquals(JAVASCRIPT_MINIFIED_INPUT, actualContent));
  275. if(nonNull(verifier)) {
  276. verifier.call();
  277. }
  278. }
  279. /**
  280. * Executes a certain test and verify if the actual path is equals to the expected one.
  281. * @param mocker The {@link Callable} responsible for performing the mocking.
  282. */
  283. private void testPath(final Callable mocker, final String expectedPath) {
  284. //given
  285. if(nonNull(mocker)) {
  286. mocker.call();
  287. }
  288. //when
  289. final InitialContent initialContent = underTest.withPath(resource)
  290. .build();
  291. //then
  292. assertTrue(initialContent.getPath().isPresent());
  293. assertEquals(expectedPath, initialContent.getPath().get());
  294. }
  295. /**
  296. * A task that returns a result. Implementors define a single method with no arguments called {@code call}.
  297. *
  298. * @since 5.0.0
  299. */
  300. private interface Callable {
  301. /**
  302. * Computes a result.
  303. */
  304. void call();
  305. }
  306. }