{"id":21332203,"url":"https://github.com/thisoecode/springacademy_cashcard-rest-api","last_synced_at":"2025-08-19T04:39:30.214Z","repository":{"id":221800831,"uuid":"754030195","full_name":"ThisoeCode/springacademy_CashCard-REST-API","owner":"ThisoeCode","description":"Spring Academy example project step-by-step following repo","archived":false,"fork":false,"pushed_at":"2024-02-12T15:51:22.000Z","size":71,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T13:51:41.825Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThisoeCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-07T09:07:24.000Z","updated_at":"2024-02-07T12:54:20.000Z","dependencies_parsed_at":"2024-02-12T16:57:41.366Z","dependency_job_id":"a41ecd98-fa7f-454b-8eb4-b8df3a5c4ddc","html_url":"https://github.com/ThisoeCode/springacademy_CashCard-REST-API","commit_stats":null,"previous_names":["thisoecode/springacademy_cashcard-rest-api"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThisoeCode%2Fspringacademy_CashCard-REST-API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThisoeCode%2Fspringacademy_CashCard-REST-API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThisoeCode%2Fspringacademy_CashCard-REST-API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThisoeCode%2Fspringacademy_CashCard-REST-API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThisoeCode","download_url":"https://codeload.github.com/ThisoeCode/springacademy_CashCard-REST-API/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243809886,"owners_count":20351407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-21T22:46:17.419Z","updated_at":"2025-03-16T01:09:31.313Z","avatar_url":"https://github.com/ThisoeCode.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e This readme file is a [Spring Academy](https://spring.academy/) learning note. \u003cbr/\u003e The coding following Spring Academy was done in VS Code instead of Spring Academy Lab.\n\n\u003e Learning \u0026 memoing starts on 2024-02-07, by Thisoe.\n\n\u003e ### \u003cspan style=\"color:yellow\"\u003eThis repo is abandoned\u003c/span\u003e\n\u003e - [Thisoe's main Spring learning repo has moved here.](https://github.com/ThisoeCode/springboot-tut_following-devtiro)\n\u003e - This repo is currently stopped. I found Spring Academy a bit not beginner friendly-ish, and at the same time, a few steps are not working on my Windows machine. \u003cbr/\u003e But this repo will be reserving archived since new SpringBoot learning repos are going to have tag-links to this file.\n\n# 1. Spring Initializr\nhttps://start.spring.io/\n\n# 2. [Set the Goal](https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/data-contracts)\nGoal API:\n```yaml\nRequest:\n  URI: /cashcards/{id}\n  HTTP Verb: GET\n  Body: None\n\nResponse:\n  HTTP Status:\n    200 OK if the user is authorized and the Cash Card was successfully retrieved\n    401 UNAUTHORIZED if the user is unauthenticated or unauthorized\n    404 NOT FOUND if the user is authenticated and authorized but the Cash Card cannot be found\n  Response Body Type: JSON\n  Example Response Body:\n    {\n      \"id\": 99,\n      \"amount\": 123.45\n    }\n```\n\n# 3. [Testing First](https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/test-first)\n- Test Driven Development (TDD)\n- The Red, Green, Refactor Loop\n  1. Red: Write a failing test for the desired functionality.\n  2. Green: Implement the simplest thing that can work to make the test pass.\n  3. Refactor: Look for opportunities to simplify, reduce duplication, or otherwise improve the code without changing any behavior—to refactor.\n  4. Repeat!\n\n\n## [Lab](https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/test-first-lab/lab)\n\n1. Write a Failing Test\n```java\npackage example.cashcard;\n\nimport org.junit.jupiter.api.Test;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nclass CashCardJsonTest {\n   @Test\n   void myFirstTest() {\n      assertThat(1).isEqualTo(42);\n   }\n}\n```\n\n[Install Gradle](https://gradle.org/install/) to run the test.\n```bash\n# Test after installation \u0026 setting env var. \ngradle -v\n# Gradle 8.6\n\ngradle init\n# Selected\n  # Generate a Gradle build from Maven build? y\n  # Build script DSL: Groovy\n\ngradle test\n# ...\n# BUILD SUCCESSFUL in 13s\n# 4 actionable tasks: 4 executed\n```\n`4 executed` means that this is a \u003cspan style='color:darkred'\u003e**failed**\u003c/span\u003e test.\nTo \"fix\" it, change the `1` in `assertThat()` to `42`.\n```java\nclass CashCardJsonTest {\n   @Test\n   void myFirstTest() {\n      assertThat(42).isEqualTo(42);\n   }\n}\n```\nNow, it passes.\n```bash\ngradle test\n# ...\n# BUILD SUCCESSFUL in 1s\n# 4 actionable tasks: 2 executed, 2 up-to-date\n```\n\nThis whole process above, is called a \"test-first development\".\n\n\n2. Testing the Data Contract\n\n```java\npackage example.cashcard;\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.autoconfigure.json.JsonTest;\nimport org.springframework.boot.test.json.JacksonTester;\nimport java.io.IOException;\nimport static org.assertj.core.api.Assertions.assertThat;\n\n@JsonTest // marks the `CashCardJsonTest` as a test class\nclass CashCardJsonTest {\n\n  @Autowired // directs Spring to create an object of the requested type\n  private JacksonTester\u003cCashCard\u003e json;\n  // `JacksonTester` handles serialization and deserialization of JSON objects\n\n  @Test\n  void cashCardSerializationTest() throws IOException {\n    CashCard cashCard = new CashCard(99L, 123.45);\n    assertThat(json.write(cashCard)).isStrictlyEqualToJson(\"expected.json\");\n    assertThat(json.write(cashCard)).hasJsonPathNumberValue(\"@.id\");\n    assertThat(json.write(cashCard)).extractingJsonPathNumberValue(\"@.id\")\n      .isEqualTo(99);\n    assertThat(json.write(cashCard)).hasJsonPathNumberValue(\"@.amount\");\n    assertThat(json.write(cashCard)).extractingJsonPathNumberValue(\"@.amount\")\n      .isEqualTo(123.45);\n  }\n}\n```\n\n\u003e Terminal run test and get failure message.\n\nWe yet neither have created `CashCard` class, nor the `expected.json` file. Let's create it **in the `main/` directory**.\n\n  1. Create file `src/main/java/example/cashcard/CashCard.java` and add content:\n```java\npackage example.cashcard;\n\nrecord CashCard(Long id, Double amount) {\n}\n```\n  2. Create file `src/test/resources/example/cashcard/expected.json` (**right click `test` directory, select `New File`, type in `resources/example/cashcard/expected.json`**) and add content:\n```json\n{}\n```\n\n\u003e Terminal run test, and...\n\n```bash\n./gradlew test\n# ...\n# Task :compileTestJava FAILED\n#   error: records are not supported in -source 8\n#   (use -source 16 or higher to enable records)\n# ...\n```\nThis error is unexpected — the tutorial did not mention this.\n\nAfter Googling and GPTing, I found the solution:\n  1. Check Java version in terminal:\n```bash\njava -version\n# java version \"17.0.10\" 2024-01-16 LTS\n```\n  2. Go to `build.gradle`, find:\n```js\njava.sourceCompatibility = JavaVersion.VERSION_1_8\n```\n  3. Change `VERSION_1_8` to `VERSION_17`.\n\nAfter these, run the test again.\n```bash\n./gradlew test --warning-mode all\n# BUILD SUCCESSFUL in 931ms\n```\n\nDifferent from tutorial again: this expects a comparison failure, but got a success.\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n___\n\u003e Repo has stopped updating.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisoecode%2Fspringacademy_cashcard-rest-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthisoecode%2Fspringacademy_cashcard-rest-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisoecode%2Fspringacademy_cashcard-rest-api/lists"}