From d89c28f64035cdfccc5b642326f444c5a4710dba Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 14:46:52 +0100 Subject: [PATCH 01/13] Create codeql.yml --- .github/workflows/codeql.yml | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..c70672a --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,84 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '20 5 * * 4' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + # required for all workflows + security-events: write + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + language: [ 'java-kotlin' ] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" From 11ae633a4a5d324674e0cd80035bb2bcd0c07b78 Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 14:48:20 +0100 Subject: [PATCH 02/13] Create detekt.yml --- .github/workflows/detekt.yml | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 .github/workflows/detekt.yml diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml new file mode 100644 index 0000000..fbab7fc --- /dev/null +++ b/.github/workflows/detekt.yml @@ -0,0 +1,118 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow performs a static analysis of your Kotlin source code using +# Detekt. +# +# Scans are triggered: +# 1. On every push to default and protected branches +# 2. On every Pull Request targeting the default branch +# 3. On a weekly schedule +# 4. Manually, on demand, via the "workflow_dispatch" event +# +# The workflow should work with no modifications, but you might like to use a +# later version of the Detekt CLI by modifing the $DETEKT_RELEASE_TAG +# environment variable. +name: Scan with Detekt + +on: + # Triggers the workflow on push or pull request events but only for default and protected branches + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '30 14 * * 1' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + # Release tag associated with version of Detekt to be installed + # SARIF support (required for this workflow) was introduced in Detekt v1.15.0 + DETEKT_RELEASE_TAG: v1.15.0 + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "scan" + scan: + name: Scan + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + + # Gets the download URL associated with the $DETEKT_RELEASE_TAG + - name: Get Detekt download URL + id: detekt_info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api graphql --field tagName=$DETEKT_RELEASE_TAG --raw-field query=' + query getReleaseAssetDownloadUrl($tagName: String!) { + repository(name: "detekt", owner: "detekt") { + release(tagName: $tagName) { + releaseAssets(name: "detekt", first: 1) { + nodes { + downloadUrl + } + } + tagCommit { + oid + } + } + } + } + ' 1> gh_response.json + + DETEKT_RELEASE_SHA=$(jq --raw-output '.data.repository.release.releaseAssets.tagCommit.oid' gh_response.json) + if [ $DETEKT_RELEASE_SHA != "37f0a1d006977512f1f216506cd695039607c3e5" ]; then + echo "Release tag doesn't match expected commit SHA" + exit 1 + fi + + DETEKT_DOWNLOAD_URL=$(jq --raw-output '.data.repository.release.releaseAssets.nodes[0].downloadUrl' gh_response.json) + echo "download_url=$DETEKT_DOWNLOAD_URL" >> $GITHUB_OUTPUT + + # Sets up the detekt cli + - name: Setup Detekt + run: | + dest=$( mktemp -d ) + curl --request GET \ + --url ${{ steps.detekt_info.outputs.download_url }} \ + --silent \ + --location \ + --output $dest/detekt + chmod a+x $dest/detekt + echo $dest >> $GITHUB_PATH + + # Performs static analysis using Detekt + - name: Run Detekt + continue-on-error: true + run: | + detekt --input ${{ github.workspace }} --report sarif:${{ github.workspace }}/detekt.sarif.json + + # Modifies the SARIF output produced by Detekt so that absolute URIs are relative + # This is so we can easily map results onto their source files + # This can be removed once relative URI support lands in Detekt: https://git.io/JLBbA + - name: Make artifact location URIs relative + continue-on-error: true + run: | + echo "$( + jq \ + --arg github_workspace ${{ github.workspace }} \ + '. | ( .runs[].results[].locations[].physicalLocation.artifactLocation.uri |= if test($github_workspace) then .[($github_workspace | length | . + 1):] else . end )' \ + ${{ github.workspace }}/detekt.sarif.json + )" > ${{ github.workspace }}/detekt.sarif.json + + # Uploads results to GitHub repository using the upload-sarif action + - uses: github/codeql-action/upload-sarif@v2 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: ${{ github.workspace }}/detekt.sarif.json + checkout_path: ${{ github.workspace }} From 0b5eb66c32890269ce57e2aad7dda62aa4dd4c91 Mon Sep 17 00:00:00 2001 From: Dobrosi Andras Date: Thu, 21 Mar 2024 15:17:41 +0100 Subject: [PATCH 03/13] all in one --- app/build.gradle.kts | 12 +- .../kotlin/feladat/ms/client/WeatherClient.kt | 11 ++ .../configuration/WeatherAppConfiguration.kt | 22 ++++ .../feladat/ms/controller/IndexController.kt | 24 ++++ .../vanio/kotlin/feladat/ms/dto/Forecast.kt | 12 ++ .../feladat/ms/service/WeatherService.kt | 25 ++++ app/src/main/resources/application.yaml | 4 + .../resources/templates/dailyAverages.html | 28 +++++ app/src/test/kotlin/WeatherAppTest.kt | 15 ++- .../feladat/ms/client/WeatherClientTest.kt | 39 ++++++ .../ms/controller/IndexControllerTest.kt | 54 +++++++++ .../feladat/ms/service/WeatherServiceTest.kt | 111 ++++++++++++++++++ gradlew | 0 13 files changed, 351 insertions(+), 6 deletions(-) create mode 100644 app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt create mode 100644 app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt create mode 100644 app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt create mode 100644 app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt create mode 100644 app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt create mode 100644 app/src/main/resources/application.yaml create mode 100644 app/src/main/resources/templates/dailyAverages.html create mode 100644 app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt create mode 100644 app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt create mode 100644 app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt mode change 100644 => 100755 gradlew diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1182c84..4c0c028 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,8 +1,8 @@ plugins { val kotlinVersion = "1.9.23" + id("org.springframework.boot") version "3.2.3" kotlin("jvm") version kotlinVersion kotlin("plugin.spring") version kotlinVersion - id("org.springframework.boot") version "3.2.3" } group = "hu.kotlin.feladat.ms" @@ -14,9 +14,17 @@ repositories { dependencies { implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-webflux") + implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") + implementation("org.jetbrains.kotlin:kotlin-reflect") + testImplementation("org.springframework.boot:spring-boot-starter-test") { + exclude("org.mockito:mockito-core") + } testImplementation(kotlin("test")) - testImplementation("io.mockk:mockk:1.4.1") + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("com.ninja-squad:springmockk:4.0.2") + testImplementation("com.github.stefanbirkner:system-lambda:1.2.1") } tasks.test { diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt new file mode 100644 index 0000000..6ecc568 --- /dev/null +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt @@ -0,0 +1,11 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.client + +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.dto.Forecast +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.client.WebClient + +@Component +class WeatherClient(@Autowired val forecast: WebClient.RequestHeadersSpec<*>) { + fun getForecast(): Forecast = forecast.retrieve().bodyToMono(Forecast::class.java).block()!! +} \ No newline at end of file diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt new file mode 100644 index 0000000..eb5208c --- /dev/null +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt @@ -0,0 +1,22 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.configuration + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.reactive.function.client.WebClient + +@Configuration +class WeatherAppConfiguration { + @Bean + fun webClient(): WebClient = WebClient.builder().build() + + @Bean + fun uriSpec(@Autowired webClient: WebClient): WebClient.RequestHeadersUriSpec<*> = webClient.get() + + @Bean + fun forecast( + @Autowired uriSpec: WebClient.RequestHeadersUriSpec<*>, + @Value("\${forecast-url}") weatherApiUrl: String + ): WebClient.RequestHeadersSpec<*> = uriSpec.uri(weatherApiUrl) +} \ No newline at end of file diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt new file mode 100644 index 0000000..b1412bc --- /dev/null +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt @@ -0,0 +1,24 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.controller + +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.service.WeatherService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.ExceptionHandler +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.servlet.ModelAndView + +@Controller +class IndexController(@Autowired val weatherService: WeatherService) { + @GetMapping("/") + fun dailyAverages(): ModelAndView = modelAndView() + .addObject("dailyAverages", weatherService.getDailyAverages()) + + @ExceptionHandler(RuntimeException::class) + fun error(): ModelAndView = modelAndView() + .addObject("dailyAverages", emptyMap()) + .addObject("error", SERVICE_UNAVAILABLE) + + private fun modelAndView() = ModelAndView("dailyAverages") +} + +const val SERVICE_UNAVAILABLE = "Service unavailable" \ No newline at end of file diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt new file mode 100644 index 0000000..88e15b3 --- /dev/null +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt @@ -0,0 +1,12 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.dto + +import java.time.LocalDateTime + +data class Forecast( + var hourly: Hourly +) + +data class Hourly ( + var time: Iterable, + var temperature_2m: Iterable +) \ No newline at end of file diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt new file mode 100644 index 0000000..0f451b0 --- /dev/null +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt @@ -0,0 +1,25 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.service + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.client.WeatherClient +import jakarta.annotation.PostConstruct +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service +import java.io.OutputStream + +@Service +class WeatherService(@Autowired val weatherClient: WeatherClient) { + @PostConstruct + fun postConstruct() { + printDailyAverages() + } + + fun printDailyAverages(out: OutputStream = System.out) = jacksonObjectMapper().writeValue(out, getDailyAverages()) + + fun getDailyAverages() = getHourly().groupBy { it.first.toLocalDate() } + .mapValues { it.value.map { pair -> pair.second }.average() } + + fun getHourly() = weatherClient.getForecast().hourly.let { + it.time.zip(it.temperature_2m) + } +} \ No newline at end of file diff --git a/app/src/main/resources/application.yaml b/app/src/main/resources/application.yaml new file mode 100644 index 0000000..1f546c1 --- /dev/null +++ b/app/src/main/resources/application.yaml @@ -0,0 +1,4 @@ +weather: + api: + url: https://api.open-meteo.com/v1/ +forecast-url: ${weather.api.url}/forecast?latitude=47.4984&longitude=19.0404&hourly=temperature_2m&timezone=auto \ No newline at end of file diff --git a/app/src/main/resources/templates/dailyAverages.html b/app/src/main/resources/templates/dailyAverages.html new file mode 100644 index 0000000..878cffd --- /dev/null +++ b/app/src/main/resources/templates/dailyAverages.html @@ -0,0 +1,28 @@ + + + + Daily Temperature Averages + + + + +

The weather service is currently unavailable.

+ + + + + + + + + +
DateDaily temperature average (°C)
+ + \ No newline at end of file diff --git a/app/src/test/kotlin/WeatherAppTest.kt b/app/src/test/kotlin/WeatherAppTest.kt index a81a55a..5fc6b3f 100644 --- a/app/src/test/kotlin/WeatherAppTest.kt +++ b/app/src/test/kotlin/WeatherAppTest.kt @@ -1,11 +1,18 @@ package hu.vanio.kotlin.feladat.ms -import kotlin.test.Test +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.service.WeatherService +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import kotlin.test.assertNotNull +@SpringBootTest class WeatherAppTest { + @Autowired + lateinit var weatherService: WeatherService - @Test fun `sikeres lekerdezes`() { - TODO() + @Test + fun testContext() { + assertNotNull(weatherService) } - } \ No newline at end of file diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt new file mode 100644 index 0000000..1cac34a --- /dev/null +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt @@ -0,0 +1,39 @@ +package hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.client + +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.dto.Forecast +import io.mockk.every +import io.mockk.impl.annotations.InjectMockKs +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.web.reactive.function.client.WebClient +import reactor.core.publisher.Mono +import kotlin.test.assertEquals + +@ExtendWith(MockKExtension::class) +class WeatherClientTest{ + @InjectMockKs + lateinit var weatherClient: WeatherClient + + @MockK + lateinit var forecastRequest: WebClient.RequestHeadersSpec<*> + + @MockK + lateinit var responseSpec: WebClient.ResponseSpec + + @MockK + lateinit var forecastMono: Mono + + @MockK + lateinit var forecast: Forecast + + @Test + fun getForecast() { + every { forecastRequest.retrieve() } returns responseSpec + every { responseSpec.bodyToMono(Forecast::class.java) } returns forecastMono + every { forecastMono.block() } returns forecast + + assertEquals(forecast, weatherClient.getForecast()) + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt new file mode 100644 index 0000000..7141136 --- /dev/null +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt @@ -0,0 +1,54 @@ +package hu.vanio.kotlin.feladat.ms.controller + +import com.ninjasquad.springmockk.MockkBean +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.controller.IndexController +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.service.WeatherService +import io.mockk.every +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.model +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import java.time.LocalDate + +@SpringBootTest +class IndexControllerTest { + + @MockkBean + lateinit var weatherService: WeatherService + + lateinit var mockMvc: MockMvc + + @BeforeEach fun init() { + mockMvc = MockMvcBuilders.standaloneSetup(IndexController(weatherService)).build() + } + + @Test + fun `when call index page`() { + every { weatherService.getDailyAverages() } returns dailyAverages + + mockMvc + .perform(get("/")) + .andExpect(status().isOk) + .andExpect(model().attribute("dailyAverages", dailyAverages)) + } + + @Test + fun `when call index page if service unavailable`() { + every { weatherService.getDailyAverages() } throws RuntimeException() + + mockMvc + .perform(get("/")) + .andExpect(status().isOk) + .andExpect(model().attribute("dailyAverages", emptyMap())) + .andExpect(model().attribute("error", "Service unavailable")) + } + +} + +val DATE: LocalDate = LocalDate.of(2024, 2, 21) +const val VALUE = 9.87 +val dailyAverages = mapOf(DATE to VALUE) \ No newline at end of file diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt new file mode 100644 index 0000000..4a85577 --- /dev/null +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt @@ -0,0 +1,111 @@ +package hu.vanio.kotlin.feladat.ms.service + +import com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOut +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.client.WeatherClient +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.dto.Forecast +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.dto.Hourly +import hu.vanio.kotlin.feladat.ms.hu.vanio.kotlin.feladat.ms.service.WeatherService +import io.mockk.InternalPlatformDsl.toStr +import io.mockk.every +import io.mockk.impl.annotations.InjectMockKs +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.io.ByteArrayOutputStream +import java.time.LocalDate +import java.time.LocalDateTime + +@ExtendWith(MockKExtension::class) +class WeatherServiceTest { + @InjectMockKs + lateinit var weatherService: WeatherService + + @MockK + lateinit var weatherClient: WeatherClient + + @BeforeEach + fun setUp() { + every { weatherClient.getForecast() } returns FORECAST + } + + @Test + fun postConstruct() { + assertEquals(EXPECTED_JSON, tapSystemOut { weatherService.postConstruct() }) + } + + @Test + fun printDailyAverages() { + val byteArrayOutputStream = ByteArrayOutputStream() + + weatherService.printDailyAverages(byteArrayOutputStream) + + assertEquals(EXPECTED_JSON, byteArrayOutputStream.toStr()) + } + + @Test + fun getDailyAverages() { + assertThat(weatherService.getDailyAverages()).isEqualTo( + mapOf( + LocalDate.of(2024, 5, 28) to 15.0, + LocalDate.of(2024, 5, 29) to 16.0 + ) + ) + } + + @Test + fun getHourly() { + assertThat(weatherService.getHourly()).isEqualTo( + listOf( + Pair(DATE1, VALUE1), + Pair(DATE2, VALUE2), + Pair(DATE3, VALUE3), + Pair(DATE4, VALUE4), + Pair(DATE5, VALUE5), + Pair(DATE6, VALUE6) + ) + ) + } + + @Test + fun getWeatherClient() { + assertEquals(weatherClient, weatherService.weatherClient) + } +} + +val DATE1: LocalDateTime = LocalDateTime.of(2024, 5, 28, 0, 0) +const val VALUE1: Double = 12.0 +val DATE2: LocalDateTime = LocalDateTime.of(2024, 5, 28, 12, 0) +const val VALUE2: Double = 18.0 +val DATE3: LocalDateTime = LocalDateTime.of(2024, 5, 29, 0, 0) +const val VALUE3: Double = 13.0 +val DATE4: LocalDateTime = LocalDateTime.of(2024, 5, 29, 6, 0) +const val VALUE4: Double = 15.0 +val DATE5: LocalDateTime = LocalDateTime.of(2024, 5, 29, 12, 0) +const val VALUE5: Double = 20.0 +val DATE6: LocalDateTime = LocalDateTime.of(2024, 5, 29, 18, 0) +const val VALUE6: Double = 16.0 +val HOURLY = + Hourly( + listOf( + DATE1, + DATE2, + DATE3, + DATE4, + DATE5, + DATE6 + ), + listOf( + VALUE1, + VALUE2, + VALUE3, + VALUE4, + VALUE5, + VALUE6 + ) + ) +val FORECAST = Forecast(HOURLY) +const val EXPECTED_JSON = "{\"2024-05-28\":15.0,\"2024-05-29\":16.0}" \ No newline at end of file diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 31310f3e39715604a143e2f84cf6605f0e294cfa Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 15:19:08 +0100 Subject: [PATCH 04/13] Delete .github/workflows/detekt.yml --- .github/workflows/detekt.yml | 118 ----------------------------------- 1 file changed, 118 deletions(-) delete mode 100644 .github/workflows/detekt.yml diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml deleted file mode 100644 index fbab7fc..0000000 --- a/.github/workflows/detekt.yml +++ /dev/null @@ -1,118 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow performs a static analysis of your Kotlin source code using -# Detekt. -# -# Scans are triggered: -# 1. On every push to default and protected branches -# 2. On every Pull Request targeting the default branch -# 3. On a weekly schedule -# 4. Manually, on demand, via the "workflow_dispatch" event -# -# The workflow should work with no modifications, but you might like to use a -# later version of the Detekt CLI by modifing the $DETEKT_RELEASE_TAG -# environment variable. -name: Scan with Detekt - -on: - # Triggers the workflow on push or pull request events but only for default and protected branches - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - schedule: - - cron: '30 14 * * 1' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -env: - # Release tag associated with version of Detekt to be installed - # SARIF support (required for this workflow) was introduced in Detekt v1.15.0 - DETEKT_RELEASE_TAG: v1.15.0 - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "scan" - scan: - name: Scan - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - # Gets the download URL associated with the $DETEKT_RELEASE_TAG - - name: Get Detekt download URL - id: detekt_info - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh api graphql --field tagName=$DETEKT_RELEASE_TAG --raw-field query=' - query getReleaseAssetDownloadUrl($tagName: String!) { - repository(name: "detekt", owner: "detekt") { - release(tagName: $tagName) { - releaseAssets(name: "detekt", first: 1) { - nodes { - downloadUrl - } - } - tagCommit { - oid - } - } - } - } - ' 1> gh_response.json - - DETEKT_RELEASE_SHA=$(jq --raw-output '.data.repository.release.releaseAssets.tagCommit.oid' gh_response.json) - if [ $DETEKT_RELEASE_SHA != "37f0a1d006977512f1f216506cd695039607c3e5" ]; then - echo "Release tag doesn't match expected commit SHA" - exit 1 - fi - - DETEKT_DOWNLOAD_URL=$(jq --raw-output '.data.repository.release.releaseAssets.nodes[0].downloadUrl' gh_response.json) - echo "download_url=$DETEKT_DOWNLOAD_URL" >> $GITHUB_OUTPUT - - # Sets up the detekt cli - - name: Setup Detekt - run: | - dest=$( mktemp -d ) - curl --request GET \ - --url ${{ steps.detekt_info.outputs.download_url }} \ - --silent \ - --location \ - --output $dest/detekt - chmod a+x $dest/detekt - echo $dest >> $GITHUB_PATH - - # Performs static analysis using Detekt - - name: Run Detekt - continue-on-error: true - run: | - detekt --input ${{ github.workspace }} --report sarif:${{ github.workspace }}/detekt.sarif.json - - # Modifies the SARIF output produced by Detekt so that absolute URIs are relative - # This is so we can easily map results onto their source files - # This can be removed once relative URI support lands in Detekt: https://git.io/JLBbA - - name: Make artifact location URIs relative - continue-on-error: true - run: | - echo "$( - jq \ - --arg github_workspace ${{ github.workspace }} \ - '. | ( .runs[].results[].locations[].physicalLocation.artifactLocation.uri |= if test($github_workspace) then .[($github_workspace | length | . + 1):] else . end )' \ - ${{ github.workspace }}/detekt.sarif.json - )" > ${{ github.workspace }}/detekt.sarif.json - - # Uploads results to GitHub repository using the upload-sarif action - - uses: github/codeql-action/upload-sarif@v2 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: ${{ github.workspace }}/detekt.sarif.json - checkout_path: ${{ github.workspace }} From 0b2e2ebe7d7ae639d9bb26ac3a17ef9fb11da20a Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 15:19:50 +0100 Subject: [PATCH 05/13] Delete .github/workflows/codeql.yml --- .github/workflows/codeql.yml | 84 ------------------------------------ 1 file changed, 84 deletions(-) delete mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index c70672a..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,84 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - schedule: - - cron: '20 5 * * 4' - -jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} - permissions: - # required for all workflows - security-events: write - - # only required for workflows in private repositories - actions: read - contents: read - - strategy: - fail-fast: false - matrix: - language: [ 'java-kotlin' ] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" From 62225b2f34f7b0b6a6395a7b0acde0c54593714e Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 17:56:22 +0100 Subject: [PATCH 06/13] Create ci.yml --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8feeb1f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,5 @@ +- name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: dobrosi/kotlin-feladat-ms From 05fa55064a19c4a83657cde4271372dcb243d591 Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 17:58:45 +0100 Subject: [PATCH 07/13] Update ci.yml --- .github/workflows/ci.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8feeb1f..ead7493 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,4 @@ -- name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4.0.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - slug: dobrosi/kotlin-feladat-ms +name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4.0.1 +with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: dobrosi/kotlin-feladat-ms From 60b18f721762b9519ef38477b8043f9d4380b27f Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 18:04:43 +0100 Subject: [PATCH 08/13] Delete .github/workflows/ci.yml --- .github/workflows/ci.yml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index ead7493..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,4 +0,0 @@ -name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4.0.1 -with: - token: ${{ secrets.CODECOV_TOKEN }} - slug: dobrosi/kotlin-feladat-ms From 5401ef9d6cda4fa20c97f696da12371b90aea56a Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 19:38:53 +0100 Subject: [PATCH 09/13] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e2589d..de864ed 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![codecov](https://codecov.io/gh/dobrosi/kotlin-feladat-ms/graph/badge.svg?token=Bv0alq4qqQ)](https://codecov.io/gh/dobrosi/kotlin-feladat-ms) # Kotlin oktatáshoz házifeladat ## Készíteni kell egy nagyon egyszerű alkalmazást / programot, az alábbi funkcionalitással From 74c1ced016b6c2f77b41223e20d20588fcc3109a Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 19:57:31 +0100 Subject: [PATCH 10/13] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index de864ed..2284c6d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![build](https://github.com/dobrosi/kotlin-feladat-ms/actions/workflows/ci.yml/badge.svg)](https://github.com/dobrosi/kotlin-feladat-ms/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/dobrosi/kotlin-feladat-ms/graph/badge.svg?token=Bv0alq4qqQ)](https://codecov.io/gh/dobrosi/kotlin-feladat-ms) # Kotlin oktatáshoz házifeladat From 1a9a3986bc28168488813fc725fe24ccd8efdca1 Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 20:05:21 +0100 Subject: [PATCH 11/13] Update --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6de1851 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: Build Gradle project + +on: + push: + +jobs: + build-gradle-project: + runs-on: ubuntu-latest + steps: + - name: Checkout project sources + uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'adopt' + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Run build with Gradle Wrapper + run: ./gradlew build + + - name: Run Kover + run: ./gradlew koverXmlReport + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: dobrosi/kotlin-feladat-ms + files: ./build/reports/kover/xmlReport.xml + fail_ci_if_error: false \ No newline at end of file From 6cced66766f9e46a1f5eafbf4628ab7fcf71b73d Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 20:06:57 +0100 Subject: [PATCH 12/13] Update build.gradle.kts --- app/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4c0c028..75756e4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,6 +1,7 @@ plugins { val kotlinVersion = "1.9.23" id("org.springframework.boot") version "3.2.3" + id("org.jetbrains.kotlinx.kover") version "0.7.6" kotlin("jvm") version kotlinVersion kotlin("plugin.spring") version kotlinVersion } From edf785782a249dc9ca568cf144b8afadd171369c Mon Sep 17 00:00:00 2001 From: dobrosi Date: Thu, 21 Mar 2024 20:28:09 +0100 Subject: [PATCH 13/13] Test (#2) * Update ci.yml * Update build.gradle.kts * Update WeatherClient.kt * Update WeatherAppConfiguration.kt * Update IndexController.kt * Update Forecast.kt * Update WeatherService.kt * Update WeatherClientTest.kt * Update IndexControllerTest.kt * Update WeatherServiceTest.kt --- .github/workflows/ci.yml | 2 +- app/build.gradle.kts | 4 ++-- .../kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt | 2 +- .../feladat/ms/configuration/WeatherAppConfiguration.kt | 2 +- .../hu/vanio/kotlin/feladat/ms/controller/IndexController.kt | 2 +- .../main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt | 2 +- .../hu/vanio/kotlin/feladat/ms/service/WeatherService.kt | 2 +- .../hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt | 2 +- .../vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt | 2 +- .../hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6de1851..be12330 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,4 +31,4 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} slug: dobrosi/kotlin-feladat-ms files: ./build/reports/kover/xmlReport.xml - fail_ci_if_error: false \ No newline at end of file + fail_ci_if_error: false diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 75756e4..b9cb97d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,9 +1,9 @@ plugins { val kotlinVersion = "1.9.23" - id("org.springframework.boot") version "3.2.3" - id("org.jetbrains.kotlinx.kover") version "0.7.6" kotlin("jvm") version kotlinVersion kotlin("plugin.spring") version kotlinVersion + id("org.springframework.boot") version "3.2.3" + id("org.jetbrains.kotlinx.kover") version "0.7.6" } group = "hu.kotlin.feladat.ms" diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt index 6ecc568..e61819e 100644 --- a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClient.kt @@ -8,4 +8,4 @@ import org.springframework.web.reactive.function.client.WebClient @Component class WeatherClient(@Autowired val forecast: WebClient.RequestHeadersSpec<*>) { fun getForecast(): Forecast = forecast.retrieve().bodyToMono(Forecast::class.java).block()!! -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt index eb5208c..1c8169a 100644 --- a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/configuration/WeatherAppConfiguration.kt @@ -19,4 +19,4 @@ class WeatherAppConfiguration { @Autowired uriSpec: WebClient.RequestHeadersUriSpec<*>, @Value("\${forecast-url}") weatherApiUrl: String ): WebClient.RequestHeadersSpec<*> = uriSpec.uri(weatherApiUrl) -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt index b1412bc..2f8262b 100644 --- a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexController.kt @@ -21,4 +21,4 @@ class IndexController(@Autowired val weatherService: WeatherService) { private fun modelAndView() = ModelAndView("dailyAverages") } -const val SERVICE_UNAVAILABLE = "Service unavailable" \ No newline at end of file +const val SERVICE_UNAVAILABLE = "Service unavailable" diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt index 88e15b3..0279e47 100644 --- a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/dto/Forecast.kt @@ -9,4 +9,4 @@ data class Forecast( data class Hourly ( var time: Iterable, var temperature_2m: Iterable -) \ No newline at end of file +) diff --git a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt index 0f451b0..c3c1047 100644 --- a/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt +++ b/app/src/main/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherService.kt @@ -22,4 +22,4 @@ class WeatherService(@Autowired val weatherClient: WeatherClient) { fun getHourly() = weatherClient.getForecast().hourly.let { it.time.zip(it.temperature_2m) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt index 1cac34a..7ccb279 100644 --- a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/client/WeatherClientTest.kt @@ -36,4 +36,4 @@ class WeatherClientTest{ assertEquals(forecast, weatherClient.getForecast()) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt index 7141136..c88b1c4 100644 --- a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/controller/IndexControllerTest.kt @@ -51,4 +51,4 @@ class IndexControllerTest { val DATE: LocalDate = LocalDate.of(2024, 2, 21) const val VALUE = 9.87 -val dailyAverages = mapOf(DATE to VALUE) \ No newline at end of file +val dailyAverages = mapOf(DATE to VALUE) diff --git a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt index 4a85577..b9bc83f 100644 --- a/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt +++ b/app/src/test/kotlin/hu/vanio/kotlin/feladat/ms/service/WeatherServiceTest.kt @@ -108,4 +108,4 @@ val HOURLY = ) ) val FORECAST = Forecast(HOURLY) -const val EXPECTED_JSON = "{\"2024-05-28\":15.0,\"2024-05-29\":16.0}" \ No newline at end of file +const val EXPECTED_JSON = "{\"2024-05-28\":15.0,\"2024-05-29\":16.0}"