diff --git a/start-client/dev/api.mock.json b/start-client/dev/api.mock.json index da16d3ef3e4..71b4492b26c 100644 --- a/start-client/dev/api.mock.json +++ b/start-client/dev/api.mock.json @@ -1,19 +1,19 @@ { "_links": { "maven-project": { - "href": "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", + "href": "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,configurationFileFormat,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated": true }, "maven-build": { - "href": "https://start.spring.io/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", + "href": "https://start.spring.io/pom.xml?type=maven-build{&dependencies,packaging,configurationFileFormat,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated": true }, "gradle-project": { - "href": "https://start.spring.io/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", + "href": "https://start.spring.io/starter.zip?type=gradle-project{&dependencies,packaging,configurationFileFormat,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated": true }, "gradle-build": { - "href": "https://start.spring.io/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", + "href": "https://start.spring.io/build.gradle?type=gradle-build{&dependencies,packaging,configurationFileFormat,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}", "templated": true }, "dependencies": { @@ -1393,6 +1393,14 @@ { "id": "war", "name": "War" } ] }, + "configurationFileFormat": { + "type": "single-select", + "default": "properties", + "values": [ + { "id": "properties", "name": "Properties" }, + { "id": "yaml", "name": "YAML" } + ] + }, "javaVersion": { "type": "single-select", "default": "1.8", diff --git a/start-client/src/components/common/builder/Fields.js b/start-client/src/components/common/builder/Fields.js index 76cc16f147d..d2ebb6186ae 100644 --- a/start-client/src/components/common/builder/Fields.js +++ b/start-client/src/components/common/builder/Fields.js @@ -108,6 +108,16 @@ function Fields({ )} + + { + update({ configurationFileFormat: value }) + }} + /> + { language: localStorage.getItem('language') || get(json, 'defaultValues').language, boot: get(json, 'defaultValues').boot, + configurationFileFormat: + localStorage.getItem('configurationFileFormat') || get(json, 'defaultValues').configurationFileFormat, meta: { name: get(json, 'defaultValues.meta').name, group: get(json, 'defaultValues.meta').group, @@ -55,7 +58,7 @@ const getPersistedOrDefault = json => { }, dependencies: [], } - const checks = ['project', 'language', 'meta.java', 'meta.packaging'] + const checks = ['project', 'language', 'meta.java', 'meta.packaging', 'configurationFileFormat',] checks.forEach(key => { const item = get(json, `lists.${key}`)?.find( it => it.key === get(values, key) @@ -80,6 +83,9 @@ const persist = changes => { if (get(changes, 'meta.java')) { localStorage.setItem('java', get(changes, 'meta.java')) } + if (get(changes, 'configurationFileFormat')) { + localStorage.setItem('configurationFileFormat', get(changes, 'configurationFileFormat')) + } } export function reducer(state, action) { diff --git a/start-client/src/components/reducer/__tests__/Initializr.js b/start-client/src/components/reducer/__tests__/Initializr.js index 23f43b046eb..c37571b2ca5 100644 --- a/start-client/src/components/reducer/__tests__/Initializr.js +++ b/start-client/src/components/reducer/__tests__/Initializr.js @@ -23,6 +23,7 @@ describe('COMPLETE action', () => { project: '', language: '', boot: '', + configurationFileFormat: '', meta: { name: '', group: '', @@ -47,7 +48,7 @@ describe('COMPLETE action', () => { }, }) expect(get(result, 'share')).toBe( - 'type=maven-project&language=java&platformVersion=2.2.0.RELEASE&packaging=jar&jvmVersion=1.8&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=' + 'type=maven-project&language=java&platformVersion=2.2.0.RELEASE&packaging=jar&configurationFileFormat=properties&jvmVersion=1.8&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=' ) expect(get(result, 'values.project')).toBe('maven-project') expect(get(result, 'values.language')).toBe('java') @@ -181,6 +182,15 @@ describe('UPDATE action', () => { }) expect(get(result, 'values.meta.packaging')).toBe('war') }) + it('should reduce the state (configuration file format)', () => { + const result = reducer(state, { + type: 'UPDATE', + payload: { + configurationFileFormat: 'yaml', + }, + }) + expect(get(result, 'values.configurationFileFormat')).toBe('yaml') + }) it('should reduce the state (meta packageName)', () => { const result = reducer(state, { type: 'UPDATE', @@ -217,6 +227,7 @@ describe('LOAD action', () => { description: 'Demo1 project for Spring Boot', groupId: 'com.example1', jvmVersion: '1.8', + configurationFileFormat: 'yaml', language: 'java', name: 'demo1', packageName: 'com.example1.demo1', @@ -239,6 +250,7 @@ describe('LOAD action', () => { expect(get(result, 'values.meta.packaging')).toBe('war') expect(get(result, 'values.meta.packageName')).toBe('com.example1.demo1') expect(get(result, 'values.meta.java')).toBe('1.8') + expect(get(result, 'values.configurationFileFormat')).toBe('yaml') expect(get(result, 'values.dependencies').length).toBe(0) expect(Object.keys(get(result, 'errors')).length).toBe(0) expect(Object.keys(get(result, 'warnings')).length).toBe(0) diff --git a/start-client/src/components/utils/ApiUtils.js b/start-client/src/components/utils/ApiUtils.js index f12bb094f9a..c926b810d07 100644 --- a/start-client/src/components/utils/ApiUtils.js +++ b/start-client/src/components/utils/ApiUtils.js @@ -10,6 +10,7 @@ const PROPERTIES_MAPPING_URL = { language: 'language', platformVersion: 'boot', packaging: 'meta.packaging', + configurationFileFormat: 'configurationFileFormat', jvmVersion: 'meta.java', groupId: 'meta.group', artifactId: 'meta.artifact', @@ -24,7 +25,7 @@ export const getInfo = function getInfo(url) { fetch(`${url}`, { method: 'GET', headers: { - Accept: 'application/vnd.initializr.v2.2+json', + Accept: 'application/vnd.initializr.v2.3+json', }, }) .then( @@ -82,6 +83,7 @@ export const parseParams = (values, queryParams, lists) => { case 'project': case 'language': case 'meta.packaging': + case 'configurationFileFormat': case 'meta.java': { const list = get(lists, key, []) const res = list.find(a => a.key.toLowerCase() === value) @@ -229,6 +231,10 @@ export const getLists = json => { text: `${packaging.name}`, })), }, + configurationFileFormat: get(json, 'configurationFileFormat.values', []).map(configurationFileFormat => ({ + key: `${configurationFileFormat.id}`, + text: `${configurationFileFormat.name}`, + })), dependencies: deps, } } @@ -238,6 +244,7 @@ export const getDefaultValues = json => { project: get(json, 'type.default'), language: get(json, 'language.default'), boot: get(json, 'bootVersion.default'), + configurationFileFormat: get(json, 'configurationFileFormat.default') || 'properties', meta: { name: get(json, 'name.default'), group: get(json, 'groupId.default'), @@ -281,6 +288,7 @@ export const getProject = function getProject(url, values, config) { packageName: get(values, 'meta.packageName'), packaging: get(values, 'meta.packaging'), javaVersion: get(values, 'meta.java'), + configurationFileFormat: get(values, 'configurationFileFormat'), }) let paramsDependencies = get(values, 'dependencies', []) .map(dependency => { diff --git a/start-client/src/components/utils/__tests__/ApiUtils.js b/start-client/src/components/utils/__tests__/ApiUtils.js index 5f28091dfc2..d49c16f68d2 100644 --- a/start-client/src/components/utils/__tests__/ApiUtils.js +++ b/start-client/src/components/utils/__tests__/ApiUtils.js @@ -38,6 +38,9 @@ describe('getDefaultValues', () => { expect(get(defaultValues, 'meta.packaging')).toBe( get(MockClient, 'packaging.default') ) + expect(get(defaultValues, 'configurationFileFormat')).toBe( + get(MockClient, 'configurationFileFormat.default') + ) expect(get(defaultValues, 'meta.packageName')).toBe( get(MockClient, 'packageName.default') ) @@ -113,6 +116,18 @@ describe('getListValues', () => { } }) + it('parse correctly the list of configuration file formats', () => { + const json = { ...MockClient } + const listsValues = getLists(json) + const listFormats = get(listsValues, 'configurationFileFormat') + const mockFormats = get(MockClient, 'configurationFileFormat.values') + expect(listFormats.length).toBe(mockFormats.length) + for (let i = 0; i < mockFormats.length; i += 1) { + expect(listFormats[i].key).toBe(mockFormats[i].id) + expect(listFormats[i].text).toBe(mockFormats[i].name) + } + }) + it('parse correctly the list of dependencies', () => { const json = { ...MockClient } const listsValues = getLists(json) @@ -151,6 +166,7 @@ describe('parseParams', () => { language: 'kotlin', platformVersion: get(defaultValues, 'boot'), packaging: 'war', + configurationFileFormat: 'yaml', jvmVersion: '11', groupId: 'com.example2', artifactId: 'demo2', @@ -168,6 +184,7 @@ describe('parseParams', () => { expect(get(result, 'values.language')).toBe('kotlin') expect(get(result, 'values.boot')).toBe(get(defaultValues, 'boot')) expect(get(result, 'values.meta.packaging')).toBe('war') + expect(get(result, 'values.configurationFileFormat')).toBe('yaml') expect(get(result, 'values.meta.java')).toBe('11') expect(get(result, 'values.meta.group')).toBe('com.example2') expect(get(result, 'values.meta.artifact')).toBe('demo2') @@ -191,6 +208,7 @@ describe('parseParams', () => { language: 'php', platformVersion: get(defaultValues, 'boot'), packaging: 'tar', + configurationFileFormat: 'xml', jvmVersion: '1', groupId: 'com.example', artifactId: 'demo', @@ -205,6 +223,7 @@ describe('parseParams', () => { expect(get(result, 'warnings.language.value')).toBe('php') expect(get(result, 'warnings.meta.packaging.value')).toBe('tar') expect(get(result, 'warnings.meta.java.value')).toBe('1') + expect(get(result, 'warnings.configurationFileFormat.value')).toBe('xml') expect(get(result, 'values.meta.group')).toBe('com.example') expect(get(result, 'values.meta.artifact')).toBe('demo') @@ -221,6 +240,9 @@ describe('parseParams', () => { expect(get(result, 'values.boot')).toBe(get(defaultValues, 'boot')) expect(get(result, 'values.meta.packaging')).toBe('jar') expect(get(result, 'values.meta.java')).toBe('1.8') + expect(get(result, 'values.configurationFileFormat')).toBe( + get(defaultValues, 'configurationFileFormat') + ) }) it('return parameters, no warning and error', () => { @@ -235,6 +257,7 @@ describe('parseParams', () => { language: 'kotlin', platformVersion: '1.1.1', packaging: 'war', + configurationFileFormat: 'properties', jvmVersion: '11', groupId: 'com.example2', artifactId: 'demo2', @@ -253,6 +276,7 @@ describe('parseParams', () => { expect(get(result, 'values.boot')).toBe(get(defaultValues, 'boot')) expect(get(result, 'values.meta.packaging')).toBe('war') expect(get(result, 'values.meta.java')).toBe('11') + expect(get(result, 'values.configurationFileFormat')).toBe('properties') expect(get(result, 'values.meta.group')).toBe('com.example2') expect(get(result, 'values.meta.artifact')).toBe('demo2') expect(get(result, 'values.meta.name')).toBe('demo2') @@ -276,6 +300,7 @@ describe('parseParams', () => { language: 'php', platformVersion: '1.1.1', packaging: 'tar', + configurationFileFormat: 'xml', jvmVersion: '1', groupId: 'com.example', artifactId: 'demo', @@ -290,6 +315,7 @@ describe('parseParams', () => { expect(get(result, 'warnings.language.value')).toBe('php') expect(get(result, 'warnings.meta.packaging.value')).toBe('tar') expect(get(result, 'warnings.meta.java.value')).toBe('1') + expect(get(result, 'warnings.configurationFileFormat.value')).toBe('xml') expect(get(result, 'errors.boot.value')).toBe('1.1.1') @@ -308,6 +334,9 @@ describe('parseParams', () => { expect(get(result, 'values.boot')).toBe(get(defaultValues, 'boot')) expect(get(result, 'values.meta.packaging')).toBe('jar') expect(get(result, 'values.meta.java')).toBe('1.8') + expect(get(result, 'values.configurationFileFormat')).toBe( + get(defaultValues, 'configurationFileFormat') + ) }) }) @@ -320,19 +349,20 @@ describe('getShareUrl', () => { project: 'foo1', language: 'foo2', boot: 'foo3', + configurationFileFormat: 'foo4', meta: { - packaging: 'foo4', - java: 'foo5', - group: 'foo6', - artifact: 'foo7', - name: 'foo8', - description: 'foo9', - packageName: 'foo10', + packaging: 'foo5', + java: 'foo6', + group: 'foo7', + artifact: 'foo8', + name: 'foo9', + description: 'foo10', + packageName: 'foo11', }, - dependencies: ['foo11', 'foo12'], + dependencies: ['foo12', 'foo13'], }) expect(result).toBe( - 'type=foo1&language=foo2&platformVersion=foo3&packaging=foo4&jvmVersion=foo5&groupId=foo6&artifactId=foo7&name=foo8&description=foo9&packageName=foo10&dependencies=foo11,foo12' + 'type=foo1&language=foo2&platformVersion=foo3&packaging=foo5&configurationFileFormat=foo4&jvmVersion=foo6&groupId=foo7&artifactId=foo8&name=foo9&description=foo10&packageName=foo11&dependencies=foo12,foo13' ) }) }) @@ -350,24 +380,25 @@ describe('getProject', () => { project: 'foo1', language: 'foo2', boot: 'foo3', + configurationFileFormat: 'foo4', meta: { - packaging: 'foo4', - java: 'foo5', - group: 'foo6', - artifact: 'foo7', - name: 'foo8', - description: 'foo9', - packageName: 'foo10', + packaging: 'foo5', + java: 'foo6', + group: 'foo7', + artifact: 'foo8', + name: 'foo9', + description: 'foo10', + packageName: 'foo11', }, - dependencies: ['foo11', 'foo12'], + dependencies: ['foo12', 'foo13'], } getProject('http://demo/starter.zip', values, [ - { id: 'foo11' }, { id: 'foo12' }, + { id: 'foo13' }, ]) expect(fetch.mock.calls.length).toEqual(1) expect(fetch.mock.calls[0][0]).toEqual( - 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo7&groupId=foo6&artifactId=foo7&name=foo8&description=foo9&packageName=foo10&packaging=foo4&javaVersion=foo5&dependencies=foo11,foo12' + 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo8&groupId=foo7&artifactId=foo8&name=foo9&description=foo10&packageName=foo11&packaging=foo5&javaVersion=foo6&configurationFileFormat=foo4&dependencies=foo12,foo13' ) }) @@ -376,21 +407,22 @@ describe('getProject', () => { project: 'foo1', language: 'foo2', boot: 'foo3', + configurationFileFormat: 'foo4', meta: { - packaging: 'foo4', - java: 'foo5', - group: 'foo6', - artifact: 'foo7', - name: 'foo8', - description: 'foo9', - packageName: 'foo10', + packaging: 'foo5', + java: 'foo6', + group: 'foo7', + artifact: 'foo8', + name: 'foo9', + description: 'foo10', + packageName: 'foo11', }, - dependencies: ['foo11', 'foo12'], + dependencies: ['foo12', 'foo13'], } - getProject('http://demo/starter.zip', values, [{ id: 'foo11' }]) + getProject('http://demo/starter.zip', values, [{ id: 'foo12' }]) expect(fetch.mock.calls.length).toEqual(1) expect(fetch.mock.calls[0][0]).toEqual( - 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo7&groupId=foo6&artifactId=foo7&name=foo8&description=foo9&packageName=foo10&packaging=foo4&javaVersion=foo5&dependencies=foo11' + 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo8&groupId=foo7&artifactId=foo8&name=foo9&description=foo10&packageName=foo11&packaging=foo5&javaVersion=foo6&configurationFileFormat=foo4&dependencies=foo12' ) }) @@ -399,20 +431,21 @@ describe('getProject', () => { project: 'foo1', language: 'foo2', boot: 'foo3', + configurationFileFormat: 'foo4', meta: { - packaging: 'foo4', - java: 'foo5', - group: 'foo6', - artifact: 'foo7', - name: 'foo8', - description: 'foo9', - packageName: 'foo10', + packaging: 'foo5', + java: 'foo6', + group: 'foo7', + artifact: 'foo8', + name: 'foo9', + description: 'foo10', + packageName: 'foo11', }, } getProject('http://demo/starter.zip', values, []) expect(fetch.mock.calls.length).toEqual(1) expect(fetch.mock.calls[0][0]).toEqual( - 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo7&groupId=foo6&artifactId=foo7&name=foo8&description=foo9&packageName=foo10&packaging=foo4&javaVersion=foo5' + 'http://demo/starter.zip?type=foo1&language=foo2&bootVersion=foo3&baseDir=foo8&groupId=foo7&artifactId=foo8&name=foo9&description=foo10&packageName=foo11&packaging=foo5&javaVersion=foo6&configurationFileFormat=foo4' ) }) })