From 74dc056be7c6092647e56d7a1ad741a7edc29435 Mon Sep 17 00:00:00 2001 From: Joar Varpe Date: Tue, 5 Nov 2024 15:38:21 +0100 Subject: [PATCH 1/4] add customFields to enable easier transfer of values from backend to frondend --- .../metadata/InitializrConfiguration.java | 12 + ...ontrollerCustomFieldsIntegrationTests.java | 127 ++++++ .../application-test-custom-fields.yml | 173 +++++++ .../metadata/config/test-custom-fields.json | 424 ++++++++++++++++++ .../metadata/config/test-default.json | 4 +- 5 files changed, 739 insertions(+), 1 deletion(-) create mode 100644 initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java create mode 100644 initializr-web/src/test/resources/application-test-custom-fields.yml create mode 100644 initializr-web/src/test/resources/metadata/config/test-custom-fields.json diff --git a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java index b403fb4f74..23eac51c0e 100644 --- a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java +++ b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java @@ -59,6 +59,18 @@ public void validate() { this.env.validate(); } + // Add customFields + private Map customFields = Collections.emptyMap(); + + // Getter and Setter + public Map getCustomFields() { + return this.customFields; + } + + public void setCustomFields(Map customFields) { + this.customFields = customFields; + } + public void merge(InitializrConfiguration other) { this.env.merge(other.env); } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java new file mode 100644 index 0000000000..42c40ddbdb --- /dev/null +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java @@ -0,0 +1,127 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.initializr.web.controller; + +import io.spring.initializr.metadata.InitializrMetadata; +import io.spring.initializr.metadata.InitializrMetadataBuilder; +import io.spring.initializr.metadata.InitializrMetadataProvider; +import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.UrlResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.web.client.HttpClientErrorException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link ProjectMetadataController} on a real http server. + * + * @author Stephane Nicoll + */ +@ActiveProfiles("test-custom-fields") +class ProjectMetadataControllerCustomFieldsIntegrationTests extends AbstractFullStackInitializrIntegrationTests { + + @Autowired + private InitializrMetadataProvider metadataProvider; + + @Test + void initializeRemoteConfig() throws Exception { + InitializrMetadata localMetadata = this.metadataProvider.get(); + InitializrMetadata metadata = InitializrMetadataBuilder.create() + .withInitializrMetadata(new UrlResource(createUrl("/metadata/config"))) + .build(); + // Basic assertions + assertThat(metadata.getDependencies().getContent()).hasSameSizeAs(localMetadata.getDependencies().getContent()); + assertThat(metadata.getTypes().getContent()).hasSameSizeAs(localMetadata.getTypes().getContent()); + assertThat(metadata.getBootVersions().getContent()).hasSameSizeAs(localMetadata.getBootVersions().getContent()); + assertThat(metadata.getPackagings().getContent()).hasSameSizeAs(localMetadata.getPackagings().getContent()); + assertThat(metadata.getJavaVersions().getContent()).hasSameSizeAs(localMetadata.getJavaVersions().getContent()); + assertThat(metadata.getLanguages().getContent()).hasSameSizeAs(localMetadata.getLanguages().getContent()); + } + + @Test + void textPlainNotAccepted() { + try { + execute("/metadata/config", String.class, null, "text/plain"); + } + catch (HttpClientErrorException ex) { + assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); + } + } + + @Test + void validateJson() throws JSONException { + ResponseEntity response = execute("/metadata/config", String.class, null, "application/json"); + validateContentType(response, MediaType.APPLICATION_JSON); + JSONObject json = new JSONObject(response.getBody()); + JSONObject expected = readJsonFrom("metadata/config/test-custom-fields.json"); + JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); + } + + @Test + void metadataClientEndpoint() { + ResponseEntity response = execute("/metadata/client", String.class, null, "application/json"); + validateDefaultMetadata(response); + } + + @Test + void dependenciesNoAcceptHeaderWithNoBootVersion() throws JSONException { + validateDependenciesMetadata("*/*", DEFAULT_METADATA_MEDIA_TYPE); + } + + @Test + void dependenciesV21WithNoBootVersion() throws JSONException { + validateDependenciesMetadata("application/vnd.initializr.v2.1+json", DEFAULT_METADATA_MEDIA_TYPE); + } + + @Test + void dependenciesV22WithNoBootVersion() throws JSONException { + validateDependenciesMetadata("application/vnd.initializr.v2.2+json", CURRENT_METADATA_MEDIA_TYPE); + } + + private void validateDependenciesMetadata(String acceptHeader, MediaType expectedMediaType) throws JSONException { + ResponseEntity response = execute("/dependencies", String.class, null, acceptHeader); + assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); + validateContentType(response, expectedMediaType); + validateDependenciesOutput("2.4.4", response.getBody()); + } + + @Test + void filteredDependencies() throws JSONException { + ResponseEntity response = execute("/dependencies?bootVersion=2.6.1", String.class, null, + "application/json"); + assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); + validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE); + validateDependenciesOutput("2.6.1", response.getBody()); + } + + protected void validateDependenciesOutput(String version, String actual) throws JSONException { + JSONObject expected = readJsonFrom("metadata/dependencies/test-dependencies-" + version + ".json"); + JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT); + } + +} diff --git a/initializr-web/src/test/resources/application-test-custom-fields.yml b/initializr-web/src/test/resources/application-test-custom-fields.yml new file mode 100644 index 0000000000..c1f4532795 --- /dev/null +++ b/initializr-web/src/test/resources/application-test-custom-fields.yml @@ -0,0 +1,173 @@ +info: + spring-boot: + version: 2.4.4 + +initializr: + customFields: + exampleField1: "Example String Value" + exampleField2: 123 + exampleField3: true + nestedField: + nestedKey1: "Nested value" + nestedKey2: 42 + env: + boms: + my-api-bom: + groupId: org.acme + artifactId: my-api-bom + versionProperty: my-api.version + additionalBoms: ['my-api-dependencies-bom'] + mappings: + - compatibilityRange: "[2.3.0.RELEASE,2.4.6)" + version: 1.0.0.RELEASE + repositories: my-api-repo-1 + - compatibilityRange: "2.4.6" + version: 2.0.0.RELEASE + repositories: my-api-repo-2 + my-api-dependencies-bom: + groupId: org.acme + artifactId: my-api-dependencies-bom + version: 1.0.0.RELEASE + repositories: my-api-repo-3 + kotlin: + defaultVersion: 1.5 + mappings: + - compatibilityRange: "[2.3.0.RELEASE,2.4.0-M1)" + version: 1.3.72 + - compatibilityRange: "[2.4.0-M1,2.5.0-M1)" + version: 1.4.31 + repositories: + my-api-repo-1: + name: repo1 + url: https://example.com/repo1 + my-api-repo-2: + name: repo2 + url: https://example.com/repo2 + my-api-repo-3: + name: repo3 + url: https://example.com/repo3 + dependencies: + - name: Core + content: + - name: Web + id: web + description: Web dependency description + facets: + - web + links: + - rel: guide + href: https://example.com/guide + description: Building a RESTful Web Service + - rel: reference + href: https://example.com/doc + - name: Security + id: security + - name: Data JPA + id: data-jpa + aliases: + - jpa + - name: Other + content: + - name: Foo + groupId: org.acme + artifactId: foo + version: 1.3.5 + weight: 42 + keywords: + - thefoo + - dafoo + links: + - rel: guide + href: https://example.com/guide1 + - rel: reference + href: https://example.com/{bootVersion}/doc + - rel: guide + href: https://example.com/guide2 + description: Some guide for foo + - name: Bar + id: org.acme:bar + version: 2.1.0 + - name: Biz + groupId: org.acme + artifactId: biz + scope: runtime + version: 1.3.5 + compatibilityRange: 2.6.0-SNAPSHOT + - name: Bur + id: org.acme:bur + version: 2.1.0 + scope: test + compatibilityRange: "[2.4.4,2.5.0-SNAPSHOT)" + - name: My API + id : my-api + groupId: org.acme + artifactId: my-api + scope: provided + bom: my-api-bom + types: + - name: Maven POM + id: maven-build + tags: + build: maven + format: build + default: false + action: /pom.xml + - name: Maven Project + id: maven-project + tags: + build: maven + format: project + default: true + action: /starter.zip + - name: Gradle Config + id: gradle-build + tags: + build: gradle + format: build + default: false + action: /build.gradle + - name: Gradle Project + id: gradle-project + tags: + build: gradle + format: project + default: false + action: /starter.zip + packagings: + - name: Jar + id: jar + default: true + - name: War + id: war + default: false + javaVersions: + - id: 1.6 + default: false + - id: 1.7 + default: false + - id: 1.8 + default: true + languages: + - name: Groovy + id: groovy + default: false + - name: Java + id: java + default: true + - name: Kotlin + id: kotlin + default: false + bootVersions: + - name : Latest SNAPSHOT + id: 2.5.0-SNAPSHOT + default: false + - name: 2.4.4 + id: 2.4.4 + default: true + - name: 2.3.10 + id: 2.3.10.RELEASE + default: false + +server: + error: + include-message: always diff --git a/initializr-web/src/test/resources/metadata/config/test-custom-fields.json b/initializr-web/src/test/resources/metadata/config/test-custom-fields.json new file mode 100644 index 0000000000..28b9ab101f --- /dev/null +++ b/initializr-web/src/test/resources/metadata/config/test-custom-fields.json @@ -0,0 +1,424 @@ +{ + "artifactId": { + "content": "demo", + "description": "project coordinates (infer archive name)", + "id": "artifactId", + "title": "Artifact", + "type": "TEXT" + }, + "bootVersions": { + "content": [ + { + "default": false, + "id": "2.5.0-SNAPSHOT", + "name": "Latest SNAPSHOT" + }, + { + "default": true, + "id": "2.4.4", + "name": "2.4.4" + }, + { + "default": false, + "id": "2.3.10.RELEASE", + "name": "2.3.10" + } + ], + "description": "spring boot version", + "id": "bootVersion", + "title": "Spring Boot Version", + "type": "SINGLE_SELECT" + }, + "configuration": { + "customFields": { + "exampleField1": "Example String Value", + "exampleField2": 123, + "exampleField3": true, + "nestedField": { + "nestedKey1": "Nested value", + "nestedKey2": 42 + } + }, + "env": { + "artifactRepository": "https://repo.spring.io/release/", + "fallbackApplicationName": "Application", + "forceSsl": false, + "gradle": { + "dependencyManagementPluginVersion": "1.0.0.RELEASE" + }, + "kotlin": { + "defaultVersion": "1.5", + "mappings": [ + { + "compatibilityRange": "[2.3.0.RELEASE,2.4.0-M1)", + "version": "1.3.72" + }, + { + "compatibilityRange": "[2.4.0-M1,2.5.0-M1)", + "version": "1.4.31" + } + ] + }, + "maven": { + "parent": { + "groupId": null, + "artifactId": null, + "version": null, + "relativePath": "", + "includeSpringBootBom": false + } + }, + "platform": { + "compatibilityRange": null, + "v1FormatCompatibilityRange": null, + "v2FormatCompatibilityRange": null + }, + "googleAnalyticsTrackingCode": null, + "invalidApplicationNames": [ + "SpringApplication", + "SpringBootApplication" + ], + "invalidPackageNames": [ + "org.springframework" + ], + "repositories": { + "my-api-repo-1": { + "name": "repo1", + "url": "https://example.com/repo1", + "releasesEnabled": true, + "snapshotsEnabled": false + }, + "my-api-repo-2": { + "name": "repo2", + "url": "https://example.com/repo2", + "releasesEnabled": true, + "snapshotsEnabled": false + }, + "my-api-repo-3": { + "name": "repo3", + "url": "https://example.com/repo3", + "releasesEnabled": true, + "snapshotsEnabled": false + }, + "spring-milestones": { + "name": "Spring Milestones", + "url": "https://repo.spring.io/milestone", + "releasesEnabled": true, + "snapshotsEnabled": false + }, + "spring-snapshots": { + "name": "Spring Snapshots", + "url": "https://repo.spring.io/snapshot", + "releasesEnabled": false, + "snapshotsEnabled": true + } + }, + "boms": { + "my-api-bom": { + "groupId": "org.acme", + "artifactId": "my-api-bom", + "versionProperty": "my-api.version", + "additionalBoms": [ + "my-api-dependencies-bom" + ], + "mappings": [ + { + "compatibilityRange": "[2.3.0.RELEASE,2.4.6)", + "repositories": [ + "my-api-repo-1" + ], + "version": "1.0.0.RELEASE" + }, + { + "compatibilityRange": "2.4.6", + "repositories": [ + "my-api-repo-2" + ], + "version": "2.0.0.RELEASE" + } + ] + }, + "my-api-dependencies-bom": { + "groupId": "org.acme", + "repositories": [ + "my-api-repo-3" + ], + "artifactId": "my-api-dependencies-bom", + "version": "1.0.0.RELEASE" + } + }, + "springBootMetadataUrl": "https://api.spring.io/projects/spring-boot/releases" + }}, + "dependencies": { + "content": [ + { + "content": [ + { + "starter": true, + "artifactId": "spring-boot-starter-web", + "description": "Web dependency description", + "facets": ["web"], + "groupId": "org.springframework.boot", + "id": "web", + "name": "Web", + "scope": "compile", + "links": [ + { + "rel": "guide", + "description": "Building a RESTful Web Service", + "href": "https://example.com/guide" + }, + { + "rel": "reference", + "href": "https://example.com/doc" + } + ] + }, + { + "starter": true, + "artifactId": "spring-boot-starter-security", + "groupId": "org.springframework.boot", + "id": "security", + "name": "Security", + "scope": "compile" + }, + { + "aliases": ["jpa"], + "starter": true, + "artifactId": "spring-boot-starter-data-jpa", + "groupId": "org.springframework.boot", + "id": "data-jpa", + "name": "Data JPA", + "scope": "compile" + } + ], + "name": "Core" + }, + { + "content": [ + { + "artifactId": "foo", + "groupId": "org.acme", + "id": "org.acme:foo", + "name": "Foo", + "weight": 42, + "starter": true, + "keywords": ["thefoo", "dafoo"], + "scope": "compile", + "version": "1.3.5", + "links": [ + { + "rel": "guide", + "href": "https://example.com/guide1" + }, + { + "rel": "reference", + "href": "https://example.com/{bootVersion}/doc", + "templated": true + }, + { + "rel": "guide", + "description": "Some guide for foo", + "href": "https://example.com/guide2" + } + ] + }, + { + "starter": true, + "artifactId": "bar", + "groupId": "org.acme", + "id": "org.acme:bar", + "name": "Bar", + "scope": "compile", + "version": "2.1.0" + }, + { + "starter": true, + "artifactId": "biz", + "groupId": "org.acme", + "id": "org.acme:biz", + "name": "Biz", + "scope": "runtime", + "version": "1.3.5", + "compatibilityRange": "2.6.0-SNAPSHOT" + }, + { + "starter": true, + "artifactId": "bur", + "groupId": "org.acme", + "id": "org.acme:bur", + "name": "Bur", + "scope": "test", + "version": "2.1.0", + "compatibilityRange": "[2.4.4,2.5.0-SNAPSHOT)" + }, + { + "starter": true, + "artifactId": "my-api", + "groupId": "org.acme", + "id": "my-api", + "name": "My API", + "scope": "provided", + "bom": "my-api-bom" + } + ], + "name": "Other" + } + ], + "description": "dependency identifiers (comma-separated)", + "id": "dependencies", + "title": "Project dependencies", + "type": "HIERARCHICAL_MULTI_SELECT" + }, + "description": { + "content": "Demo project for Spring Boot", + "description": "project description", + "id": "description", + "title": "Description", + "type": "TEXT" + }, + "groupId": { + "content": "com.example", + "description": "project coordinates", + "id": "groupId", + "title": "Group", + "type": "TEXT" + }, + "javaVersions": { + "content": [ + { + "default": false, + "id": "1.6", + "name": "1.6" + }, + { + "default": false, + "id": "1.7", + "name": "1.7" + }, + { + "default": true, + "id": "1.8", + "name": "1.8" + } + ], + "description": "language level", + "id": "javaVersion", + "title": "Java Version", + "type": "SINGLE_SELECT" + }, + "languages": { + "content": [ + { + "default": false, + "id": "groovy", + "name": "Groovy" + }, + { + "default": true, + "id": "java", + "name": "Java" + }, + { + "default": false, + "id": "kotlin", + "name": "Kotlin" + } + ], + "description": "programming language", + "id": "language", + "title": "Language", + "type": "SINGLE_SELECT" + }, + "name": { + "content": "demo", + "description": "project name (infer application name)", + "id": "name", + "title": "Name", + "type": "TEXT" + }, + "packageName": { + "content": "com.example.demo", + "description": "root package", + "id": "packageName", + "title": "Package Name", + "type": "TEXT" + }, + "packagings": { + "content": [ + { + "default": true, + "id": "jar", + "name": "Jar" + }, + { + "default": false, + "id": "war", + "name": "War" + } + ], + "description": "project packaging", + "id": "packaging", + "title": "Packaging", + "type": "SINGLE_SELECT" + }, + "types": { + "content": [ + { + "action": "/pom.xml", + "default": false, + "description": null, + "id": "maven-build", + "name": "Maven POM", + "tags": { + "build": "maven", + "format": "build" + } + }, + { + "action": "/starter.zip", + "default": true, + "description": null, + "id": "maven-project", + "name": "Maven Project", + "tags": { + "build": "maven", + "format": "project" + } + }, + { + "action": "/build.gradle", + "default": false, + "description": null, + "id": "gradle-build", + "name": "Gradle Config", + "tags": { + "build": "gradle", + "format": "build" + } + }, + { + "action": "/starter.zip", + "default": false, + "description": null, + "id": "gradle-project", + "name": "Gradle Project", + "tags": { + "build": "gradle", + "format": "project" + } + } + ], + "description": "project type", + "id": "type", + "title": "Type", + "type": "ACTION" + }, + "version": { + "content": "0.0.1-SNAPSHOT", + "description": "project version", + "id": "version", + "title": "Version", + "type": "TEXT" + } +} \ No newline at end of file diff --git a/initializr-web/src/test/resources/metadata/config/test-default.json b/initializr-web/src/test/resources/metadata/config/test-default.json index 94912920aa..18efbd772f 100644 --- a/initializr-web/src/test/resources/metadata/config/test-default.json +++ b/initializr-web/src/test/resources/metadata/config/test-default.json @@ -29,7 +29,9 @@ "title": "Spring Boot Version", "type": "SINGLE_SELECT" }, - "configuration": {"env": { + "configuration": { + "customFields": {}, + "env": { "artifactRepository": "https://repo.spring.io/release/", "fallbackApplicationName": "Application", "forceSsl": false, From 981f7268d22b0601d716474d671a1675b4f70bd1 Mon Sep 17 00:00:00 2001 From: Joar Varpe Date: Tue, 5 Nov 2024 15:45:52 +0100 Subject: [PATCH 2/4] spring-javaformat:apply --- ...ontrollerCustomFieldsIntegrationTests.java | 156 +++++++++--------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java index 42c40ddbdb..56b64a0589 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java @@ -45,83 +45,83 @@ @ActiveProfiles("test-custom-fields") class ProjectMetadataControllerCustomFieldsIntegrationTests extends AbstractFullStackInitializrIntegrationTests { - @Autowired - private InitializrMetadataProvider metadataProvider; - - @Test - void initializeRemoteConfig() throws Exception { - InitializrMetadata localMetadata = this.metadataProvider.get(); - InitializrMetadata metadata = InitializrMetadataBuilder.create() - .withInitializrMetadata(new UrlResource(createUrl("/metadata/config"))) - .build(); - // Basic assertions - assertThat(metadata.getDependencies().getContent()).hasSameSizeAs(localMetadata.getDependencies().getContent()); - assertThat(metadata.getTypes().getContent()).hasSameSizeAs(localMetadata.getTypes().getContent()); - assertThat(metadata.getBootVersions().getContent()).hasSameSizeAs(localMetadata.getBootVersions().getContent()); - assertThat(metadata.getPackagings().getContent()).hasSameSizeAs(localMetadata.getPackagings().getContent()); - assertThat(metadata.getJavaVersions().getContent()).hasSameSizeAs(localMetadata.getJavaVersions().getContent()); - assertThat(metadata.getLanguages().getContent()).hasSameSizeAs(localMetadata.getLanguages().getContent()); - } - - @Test - void textPlainNotAccepted() { - try { - execute("/metadata/config", String.class, null, "text/plain"); - } - catch (HttpClientErrorException ex) { - assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); - } - } - - @Test - void validateJson() throws JSONException { - ResponseEntity response = execute("/metadata/config", String.class, null, "application/json"); - validateContentType(response, MediaType.APPLICATION_JSON); - JSONObject json = new JSONObject(response.getBody()); - JSONObject expected = readJsonFrom("metadata/config/test-custom-fields.json"); - JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); - } - - @Test - void metadataClientEndpoint() { - ResponseEntity response = execute("/metadata/client", String.class, null, "application/json"); - validateDefaultMetadata(response); - } - - @Test - void dependenciesNoAcceptHeaderWithNoBootVersion() throws JSONException { - validateDependenciesMetadata("*/*", DEFAULT_METADATA_MEDIA_TYPE); - } - - @Test - void dependenciesV21WithNoBootVersion() throws JSONException { - validateDependenciesMetadata("application/vnd.initializr.v2.1+json", DEFAULT_METADATA_MEDIA_TYPE); - } - - @Test - void dependenciesV22WithNoBootVersion() throws JSONException { - validateDependenciesMetadata("application/vnd.initializr.v2.2+json", CURRENT_METADATA_MEDIA_TYPE); - } - - private void validateDependenciesMetadata(String acceptHeader, MediaType expectedMediaType) throws JSONException { - ResponseEntity response = execute("/dependencies", String.class, null, acceptHeader); - assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); - validateContentType(response, expectedMediaType); - validateDependenciesOutput("2.4.4", response.getBody()); - } - - @Test - void filteredDependencies() throws JSONException { - ResponseEntity response = execute("/dependencies?bootVersion=2.6.1", String.class, null, - "application/json"); - assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); - validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE); - validateDependenciesOutput("2.6.1", response.getBody()); - } - - protected void validateDependenciesOutput(String version, String actual) throws JSONException { - JSONObject expected = readJsonFrom("metadata/dependencies/test-dependencies-" + version + ".json"); - JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT); - } + @Autowired + private InitializrMetadataProvider metadataProvider; + + @Test + void initializeRemoteConfig() throws Exception { + InitializrMetadata localMetadata = this.metadataProvider.get(); + InitializrMetadata metadata = InitializrMetadataBuilder.create() + .withInitializrMetadata(new UrlResource(createUrl("/metadata/config"))) + .build(); + // Basic assertions + assertThat(metadata.getDependencies().getContent()).hasSameSizeAs(localMetadata.getDependencies().getContent()); + assertThat(metadata.getTypes().getContent()).hasSameSizeAs(localMetadata.getTypes().getContent()); + assertThat(metadata.getBootVersions().getContent()).hasSameSizeAs(localMetadata.getBootVersions().getContent()); + assertThat(metadata.getPackagings().getContent()).hasSameSizeAs(localMetadata.getPackagings().getContent()); + assertThat(metadata.getJavaVersions().getContent()).hasSameSizeAs(localMetadata.getJavaVersions().getContent()); + assertThat(metadata.getLanguages().getContent()).hasSameSizeAs(localMetadata.getLanguages().getContent()); + } + + @Test + void textPlainNotAccepted() { + try { + execute("/metadata/config", String.class, null, "text/plain"); + } + catch (HttpClientErrorException ex) { + assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); + } + } + + @Test + void validateJson() throws JSONException { + ResponseEntity response = execute("/metadata/config", String.class, null, "application/json"); + validateContentType(response, MediaType.APPLICATION_JSON); + JSONObject json = new JSONObject(response.getBody()); + JSONObject expected = readJsonFrom("metadata/config/test-custom-fields.json"); + JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); + } + + @Test + void metadataClientEndpoint() { + ResponseEntity response = execute("/metadata/client", String.class, null, "application/json"); + validateDefaultMetadata(response); + } + + @Test + void dependenciesNoAcceptHeaderWithNoBootVersion() throws JSONException { + validateDependenciesMetadata("*/*", DEFAULT_METADATA_MEDIA_TYPE); + } + + @Test + void dependenciesV21WithNoBootVersion() throws JSONException { + validateDependenciesMetadata("application/vnd.initializr.v2.1+json", DEFAULT_METADATA_MEDIA_TYPE); + } + + @Test + void dependenciesV22WithNoBootVersion() throws JSONException { + validateDependenciesMetadata("application/vnd.initializr.v2.2+json", CURRENT_METADATA_MEDIA_TYPE); + } + + private void validateDependenciesMetadata(String acceptHeader, MediaType expectedMediaType) throws JSONException { + ResponseEntity response = execute("/dependencies", String.class, null, acceptHeader); + assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); + validateContentType(response, expectedMediaType); + validateDependenciesOutput("2.4.4", response.getBody()); + } + + @Test + void filteredDependencies() throws JSONException { + ResponseEntity response = execute("/dependencies?bootVersion=2.6.1", String.class, null, + "application/json"); + assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); + validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE); + validateDependenciesOutput("2.6.1", response.getBody()); + } + + protected void validateDependenciesOutput(String version, String actual) throws JSONException { + JSONObject expected = readJsonFrom("metadata/dependencies/test-dependencies-" + version + ".json"); + JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT); + } } From c1bfb1c7968ab8c15e5bff8d939652a2d24a6a19 Mon Sep 17 00:00:00 2001 From: Joar Varpe Date: Wed, 6 Nov 2024 09:49:52 +0100 Subject: [PATCH 3/4] update with description/reasoning of customFields and reduce new test ot only test the JSON --- .../metadata/InitializrConfiguration.java | 9 +- ...ontrollerCustomFieldsIntegrationTests.java | 83 +------------------ 2 files changed, 8 insertions(+), 84 deletions(-) diff --git a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java index 23eac51c0e..380d057cf3 100644 --- a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java +++ b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java @@ -59,10 +59,15 @@ public void validate() { this.env.validate(); } - // Add customFields + /** + * The customFields feature in Spring Initializr enables additional, adaptable metadata beyond the standard fields. + * This allows organizations to set environment-specific values like default configurations, dependencies, + * version control, or deployment options—aligning generated projects directly with their standards. + * By using customFields, organizations can add new metadata flexibly without altering core configurations, + * making Initializr more adaptable and valuable for various use cases. + */ private Map customFields = Collections.emptyMap(); - // Getter and Setter public Map getCustomFields() { return this.customFields; } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java index 56b64a0589..311ba7cc73 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java @@ -16,9 +16,6 @@ package io.spring.initializr.web.controller; -import io.spring.initializr.metadata.InitializrMetadata; -import io.spring.initializr.metadata.InitializrMetadataBuilder; -import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; import org.json.JSONException; import org.json.JSONObject; @@ -26,53 +23,18 @@ import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.UrlResource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; -import org.springframework.web.client.HttpClientErrorException; - -import static org.assertj.core.api.Assertions.assertThat; /** * Integration tests for {@link ProjectMetadataController} on a real http server. * - * @author Stephane Nicoll + * @author Joar Varpe */ @ActiveProfiles("test-custom-fields") class ProjectMetadataControllerCustomFieldsIntegrationTests extends AbstractFullStackInitializrIntegrationTests { - @Autowired - private InitializrMetadataProvider metadataProvider; - - @Test - void initializeRemoteConfig() throws Exception { - InitializrMetadata localMetadata = this.metadataProvider.get(); - InitializrMetadata metadata = InitializrMetadataBuilder.create() - .withInitializrMetadata(new UrlResource(createUrl("/metadata/config"))) - .build(); - // Basic assertions - assertThat(metadata.getDependencies().getContent()).hasSameSizeAs(localMetadata.getDependencies().getContent()); - assertThat(metadata.getTypes().getContent()).hasSameSizeAs(localMetadata.getTypes().getContent()); - assertThat(metadata.getBootVersions().getContent()).hasSameSizeAs(localMetadata.getBootVersions().getContent()); - assertThat(metadata.getPackagings().getContent()).hasSameSizeAs(localMetadata.getPackagings().getContent()); - assertThat(metadata.getJavaVersions().getContent()).hasSameSizeAs(localMetadata.getJavaVersions().getContent()); - assertThat(metadata.getLanguages().getContent()).hasSameSizeAs(localMetadata.getLanguages().getContent()); - } - - @Test - void textPlainNotAccepted() { - try { - execute("/metadata/config", String.class, null, "text/plain"); - } - catch (HttpClientErrorException ex) { - assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); - } - } - @Test void validateJson() throws JSONException { ResponseEntity response = execute("/metadata/config", String.class, null, "application/json"); @@ -81,47 +43,4 @@ void validateJson() throws JSONException { JSONObject expected = readJsonFrom("metadata/config/test-custom-fields.json"); JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); } - - @Test - void metadataClientEndpoint() { - ResponseEntity response = execute("/metadata/client", String.class, null, "application/json"); - validateDefaultMetadata(response); - } - - @Test - void dependenciesNoAcceptHeaderWithNoBootVersion() throws JSONException { - validateDependenciesMetadata("*/*", DEFAULT_METADATA_MEDIA_TYPE); - } - - @Test - void dependenciesV21WithNoBootVersion() throws JSONException { - validateDependenciesMetadata("application/vnd.initializr.v2.1+json", DEFAULT_METADATA_MEDIA_TYPE); - } - - @Test - void dependenciesV22WithNoBootVersion() throws JSONException { - validateDependenciesMetadata("application/vnd.initializr.v2.2+json", CURRENT_METADATA_MEDIA_TYPE); - } - - private void validateDependenciesMetadata(String acceptHeader, MediaType expectedMediaType) throws JSONException { - ResponseEntity response = execute("/dependencies", String.class, null, acceptHeader); - assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); - validateContentType(response, expectedMediaType); - validateDependenciesOutput("2.4.4", response.getBody()); - } - - @Test - void filteredDependencies() throws JSONException { - ResponseEntity response = execute("/dependencies?bootVersion=2.6.1", String.class, null, - "application/json"); - assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull(); - validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE); - validateDependenciesOutput("2.6.1", response.getBody()); - } - - protected void validateDependenciesOutput(String version, String actual) throws JSONException { - JSONObject expected = readJsonFrom("metadata/dependencies/test-dependencies-" + version + ".json"); - JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT); - } - } From af6a91ad2578a2160951c4df663c9b53b92af597 Mon Sep 17 00:00:00 2001 From: Joar Varpe Date: Wed, 6 Nov 2024 11:44:57 +0100 Subject: [PATCH 4/4] run spring-javaformat:apply --- .../initializr/metadata/InitializrConfiguration.java | 12 +++++++----- ...tadataControllerCustomFieldsIntegrationTests.java | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java index 380d057cf3..7f2cf52aef 100644 --- a/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java +++ b/initializr-metadata/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java @@ -60,11 +60,13 @@ public void validate() { } /** - * The customFields feature in Spring Initializr enables additional, adaptable metadata beyond the standard fields. - * This allows organizations to set environment-specific values like default configurations, dependencies, - * version control, or deployment options—aligning generated projects directly with their standards. - * By using customFields, organizations can add new metadata flexibly without altering core configurations, - * making Initializr more adaptable and valuable for various use cases. + * The customFields feature in Spring Initializr enables additional, adaptable + * metadata beyond the standard fields. This allows organizations to set + * environment-specific values like default configurations, dependencies, version + * control, or deployment options—aligning generated projects directly with their + * standards. By using customFields, organizations can add new metadata flexibly + * without altering core configurations, making Initializr more adaptable and valuable + * for various use cases. */ private Map customFields = Collections.emptyMap(); diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java index 311ba7cc73..81c1659660 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectMetadataControllerCustomFieldsIntegrationTests.java @@ -43,4 +43,5 @@ void validateJson() throws JSONException { JSONObject expected = readJsonFrom("metadata/config/test-custom-fields.json"); JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); } + }