From 4e7ac7aee324a24a84334c6e05ab53b72184f9e7 Mon Sep 17 00:00:00 2001 From: "Georg M. Sorst" Date: Thu, 7 May 2026 17:46:23 +0200 Subject: [PATCH 1/3] Renovate project --- .github/workflows/ci.yaml | 2 +- README.md | 39 ++++++++++++------- app/build.gradle | 12 +++--- .../java/albums/challenge/DataService.java | 6 +-- gradle.properties | 1 + gradle/wrapper/gradle-wrapper.properties | 5 +-- 6 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 gradle.properties diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9934508..14a7e75 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: java-version: '17' diff --git a/README.md b/README.md index b0faef8..7d323b2 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,24 @@ # Albums Challenge -Your challenge is to finish this web app which lists top 100 music albums from iTunes with search and filter functionality. +Your challenge is to finish this web app which lists the top 100 music albums from iTunes with search and filter +functionality. -* Create a new private Github repository. -* Download `albums-challenge-java.zip` file from this gist and import to that repository. +* Fork this GitHub repository. * Implement the changes listed below. -* Invite members [@NostoLukas](https://github.com/NostoLukas) and [@ringaudaskalinauskas](https://github.com/ringaudaskalinauskas) with `Read` access for the review. - +* Ensure that the GitHub CI build succeeds. ## Setup ### Requirements -* `Java 17` or newer +* Java 21 or newer ### Running * `./gradlew bootRun` * Open http://localhost:8080 in your browser. -> You can also run the app from IntelliJ by running `Application` class. +* You can also run the app from IntelliJ by running `Application` class. ## Your Tasks @@ -28,23 +27,33 @@ Your challenge is to finish this web app which lists top 100 music albums from i **NOTE** -There is `tests` directory with tests that cover most of required functionality. You can run tests by executing `./gradlew test` or executing them in IntelliJ. +The [tests](app/src/test) cover most of the required functionality. You can run tests by executing `./gradlew test` or +executing them in IntelliJ. --- ### 1. Implement price and year filtering options. -- Currently, there are some hardcoded filtering options (also called facets) for price and year filters. You need to generate options that are relevant for albums that matched search query. -- Price filtering options should be displayed in ranges, e.g. 0-5, 5-10, 10-15, etc. -- Year options should be all years that match at least one album, in descending order. +- Currently, there are some hardcoded filtering options (also called facets) for price and year filters. You need to + generate options that are relevant for albums that match the search query. +- Price filtering options should be displayed in ranges, e.g., `0-5`, `5-10`, `10-15`. +- Year filter options should be all years, in descending order, that match at least one album. ### 2. Implement result filtering. - Search results can be narrowed by selecting some filtering options. -- Filters in the same group should be joined by "OR" and different groups are joined by "AND". For example, if user selects years 2018 and 2017, and price range 5-10, you should show albums which price is in range 5-10 **and** year is 2018 **or** 2017. -- When no filters are selected, show all the albums that match search query. +- Filters in the same group should be joined by `OR` and different groups are joined by `AND`. For example, if a user + selects the years 2017 and 2018, and price range `5-10`, you should show albums with a price between 5 and 10 _and_ + from 2017 _or_ 2018. +- When no filters are selected, show all albums that match the search query. ### 3. Implement count for each filtering option. -- Each filtering option has a count displayed next to it which indicates how many results are matched by the filter. The numbers have to take into account selected filters in other groups and update as user checks or unchecks filters to be accurate for the current filtering combination. -- You should show only the options that will match at least one album. Thus, filtering options might change as user selects other filters. For example, if user selected price range 0-5 and there are no albums that cost less than $5 and were released in 2017, you shouldn't show year 2017 as a filtering option. But 2017 should appear as filtering option when user selects 5-10 price range (or has no price selected) because there are some albums that were released in 2017 and cost $9.99. \ No newline at end of file +- Each filtering option has a count displayed next to it which indicates how many results are matched by the filter. The + numbers have to take into account selected filters in other groups and update as user checks or unchecks filters to be + accurate for the current filtering combination. +- You should show only the options that will match at least one album. Thus, filtering options might change when a user + selects other filters. For example, if a user selects price range `0-5` and there are no albums that cost between 0 + and 5 and were released in 2017, you shouldn't show year 2017 as a filtering option. But 2017 should appear as + a filter option when the user selects the `5-10` price range (or has no price selected) because there are some albums + that were released in 2017 and cost 9.99. \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 4bc7a9c..8e018b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,14 +1,14 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.1.5' + id 'org.springframework.boot' version "$springVersion" } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web:3.1.5' - implementation 'org.springframework.boot:spring-boot-starter-cache:3.1.5' - compileOnly 'org.springframework.boot:spring-boot-devtools:3.1.5' - testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.5' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.9.2' + implementation "org.springframework.boot:spring-boot-starter-web:$springVersion" + implementation "org.springframework.boot:spring-boot-starter-cache:$springVersion" + compileOnly "org.springframework.boot:spring-boot-devtools:$springVersion" + testImplementation "org.springframework.boot:spring-boot-starter-test:$springVersion" + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:6.0.3' } repositories { diff --git a/app/src/main/java/albums/challenge/DataService.java b/app/src/main/java/albums/challenge/DataService.java index 190e116..e867d17 100644 --- a/app/src/main/java/albums/challenge/DataService.java +++ b/app/src/main/java/albums/challenge/DataService.java @@ -6,7 +6,7 @@ import org.apache.logging.log4j.Logger; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -21,13 +21,13 @@ public class DataService { String uri = "https://itunes.apple.com/us/rss/topalbums/limit=200/json"; @Cacheable("entry") - List fetch() { + public List fetch() { logger.info("Fetching data"); var restTemplate = new RestTemplate(); var converters = restTemplate.getMessageConverters(); converters.forEach(converter -> { - if (converter instanceof MappingJackson2HttpMessageConverter jsonConverter) { + if (converter instanceof JacksonJsonHttpMessageConverter jsonConverter) { jsonConverter.setSupportedMediaTypes(Arrays.asList( new MediaType("application", "json", Charset.defaultCharset()), new MediaType("text", "javascript", Charset.defaultCharset()) diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..f922579 --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +springVersion = 4.0.6 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3fa8f86..da2e64d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ +#Thu May 07 17:32:12 CEST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip -networkTimeout=10000 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From c5b4daa437cb32d1ce501a11d64d28661a450314 Mon Sep 17 00:00:00 2001 From: "Georg M. Sorst" Date: Thu, 7 May 2026 17:56:16 +0200 Subject: [PATCH 2/3] Bump action versions --- .github/workflows/ci.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 14a7e75..84d44f0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,18 +8,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: - java-version: '17' - distribution: 'adopt' + java-version: '21' + distribution: 'corretto' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 - name: Build with Gradle - uses: gradle/gradle-build-action@v2 - with: - arguments: build + run: ./gradlew build - name: Publish Unit Test Results if: always() From d5a87628e2f16a9745003ac8064a675544c2d28d Mon Sep 17 00:00:00 2001 From: "Georg M. Sorst" Date: Thu, 7 May 2026 18:04:38 +0200 Subject: [PATCH 3/3] Bump version --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 84d44f0..b969de0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ jobs: distribution: 'corretto' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v6 - name: Build with Gradle run: ./gradlew build