Skip to content

Chatwindow#15

Closed
fredrikmohlen wants to merge 13 commits intomainfrom
Chatwindow
Closed

Chatwindow#15
fredrikmohlen wants to merge 13 commits intomainfrom
Chatwindow

Conversation

@fredrikmohlen
Copy link

@fredrikmohlen fredrikmohlen commented Nov 13, 2025

Summary by CodeRabbit

  • New Features

    • Introduced chat UI with message list, text input and send control.
    • Enabled sending and receiving messages over HTTP with live incoming message updates.
    • Added a new visual stylesheet for improved UI.
  • Tests

    • Added integration and unit tests covering sending, receiving, and model behavior.
  • Chores

    • Added environment-file ignore rule and new project dependencies; updated module requirements.

@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

Walkthrough

Adds an HTTP-backed ntfy messaging layer (interface + implementation), integrates it into the model and controller (async send/receive, observable messages), updates UI layout and styling for chat, adds dotenv/Jackson/httpclient dependencies and module requires, and introduces unit/integration tests (WireMock, spy).

Changes

Cohort / File(s) Summary
Build & Module
\.gitignore`, `pom.xml`, `src/main/java/module-info.java``
Adds .env to .gitignore; adds dependencies: dotenv-java, jackson-databind, wiremock (test), awaitility (test) in pom; module-info adds requires for dotenv, java.net.http, tools.jackson.databind, javafx.graphics.
Core Messaging
\src/main/java/com/example/NtfyConnection.java`, `src/main/java/com/example/NtfyConnectionImpl.java`, `src/main/java/com/example/NtfyMessageDto.java``
New NtfyConnection interface (async send, receive callback); NtfyConnectionImpl implements it using java.net.http HttpClient, Dotenv for HOST_NAME, Jackson for JSON parsing; NtfyMessageDto record added with @JsonIgnoreProperties.
Model Layer
\src/main/java/com/example/HelloModel.java``
HelloModel now depends on NtfyConnection, exposes ObservableList messages and StringProperty messageToSend, starts receiveMessage in constructor, provides sendMessage returning CompletableFuture, and marshals incoming messages to the JavaFX thread via Platform.runLater.
Controller & UI
\src/main/java/com/example/HelloController.java`, `src/main/java/com/example/HelloFX.java`, `src/main/resources/com/example/hello-view.fxml`, `src/main/resources/css/style.css``
HelloController gains ListView binding, TextArea and Button fields, custom cell factory, and sendMessage handler; HelloFX has minor whitespace change; FXML replaced with VBox layout including messageView, chatArea, chatButton; new stylesheet added for list, textarea, and button styling.
Testing
\src/test/java/com/example/HelloModelTest.java`, `src/test/java/com/example/NtfyConnectionSpy.java``
Adds HelloModelTest with WireMock and Awaitility integration tests; NtfyConnectionSpy test double captures sent messages and can simulate incoming messages for tests.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as HelloController
    participant Model as HelloModel
    participant Conn as NtfyConnectionImpl
    participant Server as HTTP Server

    rect rgb(200,220,255)
    Note over User,Server: Send message (async)
    User->>UI: click send / enter text
    UI->>Model: set messageToSend & call sendMessage()
    Model->>Conn: send(message) (returns CompletableFuture)
    Conn->>Server: POST /mytopic (async)
    Server-->>Conn: 200 OK
    Conn-->>Model: CompletableFuture completes
    Model-->>UI: observable/completion update
    end

    rect rgb(220,255,200)
    Note over Conn,Server: Receive (stream/poll)
    Conn->>Server: GET /mytopic/json (async)
    Server-->>Conn: JSON lines stream
    Conn->>Conn: parse → NtfyMessageDto, filter event=="message"
    Conn->>Model: messageHandler.accept(dto)
    Model->>Model: Platform.runLater -> append to messages
    Model-->>UI: ListView updates via binding
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • src/main/java/com/example/NtfyConnectionImpl.java (async HttpClient usage, stream parsing, JSON handling, dotenv resolution, error logging).
    • src/main/java/com/example/HelloModel.java (threading, Platform.runLater, CompletableFuture chaining).
    • FXML ids vs controller fields in src/main/resources/com/example/hello-view.fxml and src/main/java/com/example/HelloController.java.
    • Tests using WireMock/Awaitility for timing/flakiness in src/test/java/*.

Poem

🐰 I hopped a note through POST and stream,

DTOs gleamed like stars in my dream,
Async paws tapped, messages flowed,
ListView filled where wild carrots glowed,
Tests mock the burrow — what a beam! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.41% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Chatwindow' is vague and lacks specificity about the actual changes made. While a chatwindow feature is being added, the title doesn't convey meaningful details about what was changed or why. Consider a more descriptive title such as 'Add ntfy-based messaging UI with live message handling' or 'Implement chat interface with async message service integration' to better convey the scope of changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (14)
pom.xml (2)

48-69: Consider using properties for new dependency versions.

The existing dependencies use properties (e.g., ${junit.jupiter.version}), but the new dependencies have hardcoded versions. For consistency and easier maintenance, consider defining properties for these versions.

Apply this diff:

         <javafx.version>25</javafx.version>
+        <dotenv.version>3.2.0</dotenv.version>
+        <jackson.version>2.18.2</jackson.version>
+        <wiremock.version>3.10.0</wiremock.version>
+        <awaitility.version>4.3.0</awaitility.version>
     </properties>

Then reference them in the dependencies:

         <dependency>
             <groupId>io.github.cdimascio</groupId>
             <artifactId>dotenv-java</artifactId>
-            <version>3.2.0</version>
+            <version>${dotenv.version}</version>
         </dependency>

58-63: Consider upgrading to the latest stable WireMock version.

The dependency currently uses a beta version (4.0.0-beta.15). The latest stable WireMock release is 3.13.1 (released June 12, 2025). For better stability and compatibility, consider updating to 3.13.1.

src/main/resources/css/style.css (3)

6-6: Remove commented-out code.

The commented gradient configuration should be removed to keep the CSS clean.

     -fx-background-color: #ffffff, linear-gradient(to bottom, #8b0000, #ffd700);
-   /* -fx-background-color: linear-gradient(to bottom, #8b0000, #ffd700);*/
     -fx-background-insets: 0, 4;

12-14: Remove commented-out code.

Clean up the commented list-view styles.

 }
-/*.list-view{*/
-/*    -fx-background-color: linear-gradient(to bottom, #8b0000, #ffd700);*/
-/*}*/
 .list-view {

16-16: Replace Swedish comments with English.

The CSS contains comments in Swedish. For international collaboration and maintainability, consider using English comments.

Example translations:

  • Line 16: "Gör bakgrunden transparent" → "Make background transparent"
  • Line 19: "Ta bort kantlinje" → "Remove border"
  • Line 29: "Ta bort bakgrund och kantlinje när musen är över" → "Remove background and border on hover"

Also applies to: 19-19, 29-29, 34-36, 42-43, 46-46

src/main/java/com/example/NtfyMessageDto.java (1)

6-6: Consider formatting the record for better readability.

The record definition has all five fields on one line, which impacts readability. Consider formatting it with one field per line or logical groupings.

 @JsonIgnoreProperties(ignoreUnknown = true)
-public record NtfyMessageDto(String id,long time, String event, String topic, String message){}
+public record NtfyMessageDto(
+    String id,
+    long time,
+    String event,
+    String topic,
+    String message
+) {}

Additionally, note the missing space after the comma between id and long time.

src/main/java/com/example/NtfyConnection.java (1)

8-10: Remove redundant public modifiers from interface methods.

Interface methods are implicitly public in Java. The explicit public modifiers are redundant and can be removed for cleaner code.

 public interface NtfyConnection {
 
-    public CompletableFuture<Void> send(String message);
+    CompletableFuture<Void> send(String message);
 
-    public void receive(Consumer<NtfyMessageDto> messageHandler);
+    void receive(Consumer<NtfyMessageDto> messageHandler);
 }
src/main/java/com/example/HelloController.java (1)

15-15: Consider using dependency injection instead of creating NtfyConnectionImpl directly.

The controller creates its own NtfyConnectionImpl instance, which creates tight coupling and makes testing difficult. Consider using constructor injection or a factory pattern.

 public class HelloController {
 
-    private final HelloModel model = new HelloModel(new NtfyConnectionImpl());
+    private final HelloModel model;
     public ListView<NtfyMessageDto> messageView;
+    
+    public HelloController() {
+        this(new HelloModel(new NtfyConnectionImpl()));
+    }
+    
+    // Constructor for testing
+    HelloController(HelloModel model) {
+        this.model = model;
+    }

This allows test code to inject a mock model.

src/test/java/com/example/NtfyConnectionSpy.java (1)

8-8: Make the message field private for proper encapsulation.

The field should be private and exposed via a getter method if test assertions need to access it.

Apply this diff:

-    String message;
+    private String message;

Add a getter method after line 9:

    public String getMessage() {
        return message;
    }

And update test assertions to use spy.getMessage() instead of spy.message.

src/test/java/com/example/HelloModelTest.java (3)

27-36: Use English for all code comments.

The comments are in Swedish while the code is in English. For maintainability and collaboration, all comments should be in English.

Apply this diff:

     /**
-     * Initierar JavaFX Toolkit en gång innan alla tester i klassen.
+     * Initializes the JavaFX Toolkit once before all tests in the class.
      */
     @BeforeAll
     public static void initToolkit() {
-        // Kontrollera om Toolkiten redan är igång för att undvika IllegalStateException
+        // Check if the Toolkit is already running to avoid IllegalStateException
         try {
             Platform.startup(() -> {
             });
         } catch (IllegalStateException e) {
-            // Toolkit är redan igång, ignorera
+            // Toolkit is already running, ignore
         }
     }

88-106: Translate Swedish comments to English.

Line 101 contains a Swedish comment. For consistency and maintainability, use English throughout.

Apply this diff:

                 .atMost(Duration.ofSeconds(4))
-                .pollInterval(Duration.ofMillis(100)) // Kolla var 100:e ms
+                .pollInterval(Duration.ofMillis(100)) // Check every 100ms
                 .untilAsserted(() -> {

110-121: Translate Swedish comments to English.

Lines 108, 114, and 118 contain Swedish comments. Maintain consistency by using English throughout the codebase.

Apply this diff:

-    // Test som skickar in ett fake:at meddelande via record och kollar att meddelandet finns i observablelistan
+    // Test that sends a fake message via record and verifies that the message appears in the observable list
     @Test
     void checkThatReceivedFakeMessageAppearInList() {
         var spy = new NtfyConnectionSpy();
         var model = new HelloModel(spy);
 
-        //Skapa ett meddelande genom en record och skicka den till listan
+        // Create a message through a record and send it to the list
         var fakeMessage = new NtfyMessageDto("id1", 1746598362, "message", "fmtopic", "Hallå");
         spy.simulateIncomingMessage(fakeMessage);
 
-        // kontrollera att Meddelandet finns i listan
+        // Verify that the message is in the list
         assertThat(model.getMessages()).extracting(NtfyMessageDto::message).contains("Hallå");
 
     }
src/main/java/com/example/NtfyConnectionImpl.java (1)

45-47: Remove outdated TODO comments.

The TODO comments about handling blocking requests are no longer relevant since the code already uses sendAsync, which returns a CompletableFuture and doesn't block. These comments should be removed to avoid confusion.

Apply this diff:

                 });
     }
-//            // Todo: handle long blocking send request to not freeze the java FX thread
-//            //1. Use thread send message?
-//            //2. Use async?
 
     @Override
src/main/java/com/example/HelloModel.java (1)

54-61: Remove commented code and extra blank lines.

Line 57 contains commented-out code that should be removed. Lines 60-61 have unnecessary extra blank lines.

The use of Platform.runLater on line 56 is correct for ensuring UI updates happen on the JavaFX thread.

Apply this diff:

     public void receiveMessage() {
 
-        connection.receive(m->Platform.runLater(()-> messages.add(m)));
-//
+        connection.receive(m -> Platform.runLater(() -> messages.add(m)));
     }
 }
-
-
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21c51e8 and 711e436.

📒 Files selected for processing (13)
  • .gitignore (1 hunks)
  • pom.xml (1 hunks)
  • src/main/java/com/example/HelloController.java (2 hunks)
  • src/main/java/com/example/HelloFX.java (2 hunks)
  • src/main/java/com/example/HelloModel.java (2 hunks)
  • src/main/java/com/example/NtfyConnection.java (1 hunks)
  • src/main/java/com/example/NtfyConnectionImpl.java (1 hunks)
  • src/main/java/com/example/NtfyMessageDto.java (1 hunks)
  • src/main/java/module-info.java (1 hunks)
  • src/main/resources/com/example/hello-view.fxml (1 hunks)
  • src/main/resources/css/style.css (1 hunks)
  • src/test/java/com/example/HelloModelTest.java (1 hunks)
  • src/test/java/com/example/NtfyConnectionSpy.java (1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/main/resources/css/style.css

[error] 7-7: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 8-8: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 9-9: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 16-16: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 17-17: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 18-18: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 19-19: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 21-21: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 22-22: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 25-25: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 26-26: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 27-27: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 30-30: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 31-31: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 32-32: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 37-37: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 37-38: Unexpected unknown pseudo-class selected

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 39-39: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 40-40: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 43-43: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 43-43: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 47-47: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 47-48: Unexpected unknown pseudo-class selected

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 48-50: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 51-51: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 52-53: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 53-54: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 54-56: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 56-57: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 57-57: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 58-58: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 58-58: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 61-62: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 62-63: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 63-64: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 64-64: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 65-66: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 66-66: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 69-70: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)

🔇 Additional comments (8)
.gitignore (1)

3-3: Good security practice—environment files should not be committed.

Adding .env to .gitignore aligns with the PR's introduction of dotenv-java and environment-driven configuration (HOST_NAME via NtfyConnectionImpl). This prevents accidental commits of sensitive or environment-specific configuration.

src/main/resources/com/example/hello-view.fxml (1)

8-9: Stylesheet path correctly resolves to existing file.

Verified that src/main/resources/css/style.css exists and the relative path @../../css/style.css from src/main/resources/com/example/hello-view.fxml resolves correctly at runtime.

pom.xml (1)

53-57: Let me verify if the exact artifact exists with a more direct query:

The artifact tools.jackson.core:jackson-databind:3.0.1 exists on Maven Central and is published to Maven Central repository. The review comment is incorrect.

For Jackson 3.x, groupIds start with tools.jackson (instead of com.fasterxml.jackson). Jackson Version 3.0 is a Major New version, released on October 3, 2025—not in development. The code in this PR is correct and requires no changes.

Likely an incorrect or invalid review comment.

src/test/java/com/example/NtfyConnectionSpy.java (1)

24-27: LGTM!

The null check before invoking the handler is good defensive programming and prevents potential NPEs in test scenarios.

src/test/java/com/example/HelloModelTest.java (1)

40-49: Well-structured unit test with good Given/When/Then organization.

The test effectively verifies the delegation to the connection. Note that line 48 will need to be updated to spy.getMessage() if the encapsulation suggestion for NtfyConnectionSpy is applied.

src/main/java/com/example/NtfyConnectionImpl.java (1)

21-28: LGTM!

Both constructors are well-designed. The use of Objects.requireNonNull in the default constructor provides clear failure messages if the HOST_NAME environment variable is missing.

src/main/java/com/example/HelloModel.java (2)

34-48: LGTM!

The accessor and mutator methods follow standard JavaFX property patterns correctly.


50-52: LGTM!

The method correctly delegates to the connection and returns the CompletableFuture for callers to handle completion as needed.

Comment on lines +30 to +44
@Override
public CompletableFuture<Void> send(String message) {
HttpRequest httpRequest = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(message))
.header("Cache", "no")
.uri(URI.create(hostName + "/mytopic"))
.build();

return http.sendAsync(httpRequest, HttpResponse.BodyHandlers.discarding())
.thenAccept(response -> System.out.println("Message sent!"))
.exceptionally(e -> {
System.out.println("Error sending message");
return null;
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix the Cache header and use proper logging.

Line 34 uses an incorrect header name "Cache". The correct header for cache control is "Cache-Control". Additionally, lines 39 and 41 use System.out.println instead of a proper logging framework, which limits production observability.

Apply this diff:

     public CompletableFuture<Void> send(String message) {
         HttpRequest httpRequest = HttpRequest.newBuilder()
                 .POST(HttpRequest.BodyPublishers.ofString(message))
-                .header("Cache", "no")
+                .header("Cache-Control", "no-cache")
                 .uri(URI.create(hostName + "/mytopic"))
                 .build();
 
         return http.sendAsync(httpRequest, HttpResponse.BodyHandlers.discarding())
-                .thenAccept(response -> System.out.println("Message sent!"))
+                .thenAccept(response -> logger.info("Message sent successfully"))
                 .exceptionally(e -> {
-                    System.out.println("Error sending message");
+                    logger.error("Error sending message", e);
                     return null;
                 });
     }

You'll need to add a logger field:

private static final Logger logger = LoggerFactory.getLogger(NtfyConnectionImpl.class);
🤖 Prompt for AI Agents
In src/main/java/com/example/NtfyConnectionImpl.java around lines 30 to 44, the
HTTP request uses the wrong header name ("Cache") and the method uses
System.out.println for logging; add a logger field (private static final Logger
logger = LoggerFactory.getLogger(NtfyConnectionImpl.class)); change the header
to "Cache-Control", replace the success print with logger.info("Message sent!"),
and replace the exception handler to log the error with logger.error("Error
sending message", e) (ensure the exception is captured in the exceptionally
block).

Comment on lines +49 to +63
@Override
public void receive (Consumer < NtfyMessageDto > messageHandler) {
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create(hostName + "/mytopic/json"))
.build();

http.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines())
.thenAccept(response -> response.body()
.map(s ->
mapper.readValue(s, NtfyMessageDto.class))
.filter(message -> message.event().equals("message"))
.peek(System.out::println)
.forEach(messageHandler));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix critical exception handling and indentation issues.

Multiple issues in the receive method:

  1. Lines 49-50: Inconsistent indentation - method is incorrectly indented.
  2. Line 59: mapper.readValue(s, NtfyMessageDto.class) throws checked IOException, but it's used in a lambda that doesn't declare this exception. This will either fail to compile or require exception wrapping.
  3. Line 61: Using System.out.println instead of proper logging.

Apply this diff:

-        @Override
-        public void receive (Consumer < NtfyMessageDto > messageHandler) {
-            HttpRequest httpRequest = HttpRequest.newBuilder()
-                    .GET()
-                    .uri(URI.create(hostName + "/mytopic/json"))
-                    .build();
-
-            http.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines())
-                    .thenAccept(response -> response.body()
-                            .map(s ->
-                                    mapper.readValue(s, NtfyMessageDto.class))
-                            .filter(message -> message.event().equals("message"))
-                            .peek(System.out::println)
-                            .forEach(messageHandler));
-        }
+    @Override
+    public void receive(Consumer<NtfyMessageDto> messageHandler) {
+        HttpRequest httpRequest = HttpRequest.newBuilder()
+                .GET()
+                .uri(URI.create(hostName + "/mytopic/json"))
+                .build();
+
+        http.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines())
+                .thenAccept(response -> response.body()
+                        .map(s -> {
+                            try {
+                                return mapper.readValue(s, NtfyMessageDto.class);
+                            } catch (Exception e) {
+                                logger.error("Failed to parse message: {}", s, e);
+                                return null;
+                            }
+                        })
+                        .filter(message -> message != null && message.event().equals("message"))
+                        .peek(message -> logger.debug("Received message: {}", message))
+                        .forEach(messageHandler));
     }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/com/example/NtfyConnectionImpl.java around lines 49 to 63, fix
indentation and exception handling in receive: un-indent the method to match
class formatting, replace the lambda that calls mapper.readValue(s,
NtfyMessageDto.class) with code that handles the checked IOException (e.g., map
each line inside a try-catch that logs parsing errors and skips invalid lines,
or call a helper that wraps IOException into an unchecked exception), and
replace System.out.println with the class logger (create/use a private static
final Logger if not present) to log the parsed message at an appropriate level;
ensure the asynchronous pipeline still calls the provided messageHandler only
for successfully parsed messages with event "message".

requires javafx.fxml;
requires io.github.cdimascio.dotenv.java;
requires java.net.http;
requires tools.jackson.databind;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Incorrect module name for Jackson databind.

The module name tools.jackson.databind is incorrect. This corresponds to the wrong groupId in pom.xml. The correct module name for Jackson databind is com.fasterxml.jackson.databind.

     requires java.net.http;
-    requires tools.jackson.databind;
+    requires com.fasterxml.jackson.databind;
     requires javafx.graphics;

This must be fixed alongside the pom.xml groupId correction.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
requires tools.jackson.databind;
requires com.fasterxml.jackson.databind;
🤖 Prompt for AI Agents
In src/main/java/module-info.java around line 6, the module declaration uses the
incorrect module name "tools.jackson.databind"; change it to
"com.fasterxml.jackson.databind" and ensure the project's pom.xml groupId is
corrected to match the official Jackson coordinates so the module name resolves
correctly; update the requires clause to the correct module name and verify
build imports and module-path references compile successfully.

Comment on lines +68 to +85
void checkReceivedMessagesAfterSendingAMessageToServer() throws InterruptedException {
//Arrange
var conImp = new NtfyConnectionImpl();
var model = new HelloModel(conImp);
model.setMessageToSend("Hello World");
//Act - When

model.sendMessage().join();

//Assert
Awaitility.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Duration.ofMillis(100))
.untilAsserted(() -> {
assertThat(model.getMessages()).isNotEmpty();
assertThat(model.getMessages().getLast().message()).contains("Hello World");
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Test depends on real external service - breaks test isolation.

Line 70 creates NtfyConnectionImpl() without parameters, which loads the HOST_NAME from environment variables and connects to a real external service. This makes the test:

  • Flaky (depends on external service availability)
  • Slow (real network I/O)
  • Non-isolated (not truly a unit/integration test)

Additionally, line 83 uses .getLast() which requires Java 21+, potentially limiting compatibility.

Apply this diff to use WireMock like the other tests:

     @Test
-    void checkReceivedMessagesAfterSendingAMessageToServer() throws InterruptedException {
+    void checkReceivedMessagesAfterSendingAMessageToServer(WireMockRuntimeInfo wmRunTimeInfo) throws InterruptedException {
         //Arrange
-        var conImp = new NtfyConnectionImpl();
+        var conImp = new NtfyConnectionImpl("http://localhost:" + wmRunTimeInfo.getHttpPort());
         var model = new HelloModel(conImp);
         model.setMessageToSend("Hello World");
+        
+        stubFor(post("/mytopic").willReturn(ok()));
+        stubFor(get("/mytopic/json")
+                .willReturn(aResponse()
+                        .withHeader("Content-type", "application/json")
+                        .withBody("{\"event\": \"message\",\"message\": \"Hello World\", \"time\": \"12314244\"}")));
+        
         //Act - When
 
         model.sendMessage().join();
 
         //Assert
         Awaitility.await()
                 .atMost(Duration.ofSeconds(5))
                 .pollInterval(Duration.ofMillis(100))
                 .untilAsserted(() -> {
                     assertThat(model.getMessages()).isNotEmpty();
-                    assertThat(model.getMessages().getLast().message()).contains("Hello World");
+                    assertThat(model.getMessages().get(model.getMessages().size() - 1).message()).contains("Hello World");
                 });
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void checkReceivedMessagesAfterSendingAMessageToServer() throws InterruptedException {
//Arrange
var conImp = new NtfyConnectionImpl();
var model = new HelloModel(conImp);
model.setMessageToSend("Hello World");
//Act - When
model.sendMessage().join();
//Assert
Awaitility.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Duration.ofMillis(100))
.untilAsserted(() -> {
assertThat(model.getMessages()).isNotEmpty();
assertThat(model.getMessages().getLast().message()).contains("Hello World");
});
}
void checkReceivedMessagesAfterSendingAMessageToServer(WireMockRuntimeInfo wmRunTimeInfo) throws InterruptedException {
//Arrange
var conImp = new NtfyConnectionImpl("http://localhost:" + wmRunTimeInfo.getHttpPort());
var model = new HelloModel(conImp);
model.setMessageToSend("Hello World");
stubFor(post("/mytopic").willReturn(ok()));
stubFor(get("/mytopic/json")
.willReturn(aResponse()
.withHeader("Content-type", "application/json")
.withBody("{\"event\": \"message\",\"message\": \"Hello World\", \"time\": \"12314244\"}")));
//Act - When
model.sendMessage().join();
//Assert
Awaitility.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Duration.ofMillis(100))
.untilAsserted(() -> {
assertThat(model.getMessages()).isNotEmpty();
assertThat(model.getMessages().get(model.getMessages().size() - 1).message()).contains("Hello World");
});
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/main/java/com/example/HelloController.java (1)

16-16: Add @FXML annotation and make messageView private.

The messageView field should be annotated with @FXML and made private, consistent with other FXML-injected fields (chatArea, chatButton).

Apply this diff:

-    public ListView<NtfyMessageDto> messageView;
+    
+    @FXML
+    private ListView<NtfyMessageDto> messageView;
src/main/java/com/example/HelloModel.java (1)

21-24: Avoid starting async operations in the constructor.

Calling receiveMessage() from the constructor starts asynchronous operations before the object is fully constructed, which can lead to:

  • The this reference escaping before construction completes
  • Potential issues with subclass overrides accessing uninitialized state
  • Complications in testing and lifecycle management

Consider requiring explicit initialization:

     public HelloModel(NtfyConnection connection) {
         this.connection = connection;
-        receiveMessage();
+    }
+    
+    public void initialize() {
+        receiveMessage();
     }

Then update callers (e.g., HelloController) to call model.initialize() after construction.

🧹 Nitpick comments (3)
src/main/java/com/example/NtfyConnection.java (1)

6-11: Consider adding documentation to clarify contract.

The interface lacks Javadoc explaining the threading model, error handling expectations, and usage patterns. Consider documenting:

  • Whether send() can be called concurrently
  • How errors are propagated in the returned CompletableFuture
  • When and on which thread the messageHandler in receive() will be invoked
  • Whether receive() can be called multiple times or only once
src/main/java/com/example/HelloController.java (2)

41-41: Rename parameter to avoid shadowing.

The parameter name List shadows the java.util.List type. Consider renaming it to listView or lv for clarity.

Apply this diff:

-        return List -> new ListCell<>() {
+        return listView -> new ListCell<>() {

19-19: Remove the unused myTextArea field.

The myTextArea field at line 19 is declared with @FXML but has no corresponding binding in the FXML file (only chatArea is bound), and it is never referenced in the controller code. Remove this field.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 711e436 and 72eee3b.

📒 Files selected for processing (8)
  • src/main/java/com/example/HelloController.java (2 hunks)
  • src/main/java/com/example/HelloFX.java (1 hunks)
  • src/main/java/com/example/HelloModel.java (2 hunks)
  • src/main/java/com/example/NtfyConnection.java (1 hunks)
  • src/main/java/com/example/NtfyConnectionImpl.java (1 hunks)
  • src/main/java/com/example/NtfyMessageDto.java (1 hunks)
  • src/main/resources/css/style.css (1 hunks)
  • src/test/java/com/example/HelloModelTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/java/com/example/NtfyMessageDto.java
  • src/main/java/com/example/NtfyConnectionImpl.java
  • src/test/java/com/example/HelloModelTest.java
🧰 Additional context used
🪛 Biome (2.1.2)
src/main/resources/css/style.css

[error] 6-6: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 7-7: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 8-8: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 12-12: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 13-13: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 14-14: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 15-15: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 16-16: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 17-17: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 20-20: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 21-21: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 22-22: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 23-23: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 26-26: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 27-27: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 28-28: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 31-31: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 31-31: Unexpected unknown pseudo-class selected

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 33-33: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 34-34: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 36-36: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 36-36: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 39-39: Unexpected unknown pseudo-class filled

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 39-39: Unexpected unknown pseudo-class selected

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 40-40: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 43-43: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 44-44: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 45-45: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 46-46: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 48-48: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 49-49: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 50-50: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 50-50: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 53-53: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 54-54: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 55-55: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 56-56: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 57-57: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 60-60: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)

🔇 Additional comments (4)
src/main/java/com/example/HelloFX.java (1)

13-13: LGTM! Previous unused import issue has been addressed.

The blank line addition has no functional impact, and the previously flagged unused Dotenv import has been removed.

src/main/resources/css/style.css (1)

1-61: LGTM! Static analysis warnings are false positives.

The stylesheet uses valid JavaFX CSS properties. The static analysis tool (Biome) is flagging -fx- prefixed properties and JavaFX-specific pseudo-classes (:filled, :selected) as unknown because it's designed for web CSS, not JavaFX CSS. All properties used here are valid JavaFX CSS syntax.

The previously flagged -fx-transition property has been removed, which was correct since JavaFX CSS doesn't support CSS transitions.

src/main/java/com/example/HelloController.java (1)

54-61: LGTM! Previous issues with sendMessage have been addressed.

The method now properly reads from chatArea, validates input, updates the model, and clears the input field. The null check in the cell factory (line 45) has also been correctly implemented.

src/main/java/com/example/HelloModel.java (1)

58-66: Nice defensive pattern for JavaFX toolkit initialization!

The runOnFx utility elegantly handles the case where the JavaFX toolkit isn't initialized (e.g., during unit tests) by catching IllegalStateException and running the task inline. This allows the model to be tested without requiring a full JavaFX environment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/test/java/com/example/HelloModelTest.java (1)

67-67: Use .get(size - 1) for broader Java compatibility.

.getLast() requires Java 21+. For wider compatibility, use the traditional approach.

Apply this diff:

-                    assertThat(model.getMessages().getLast().message()).isEqualTo("Hello World");
+                    assertThat(model.getMessages().get(model.getMessages().size() - 1).message()).isEqualTo("Hello World");
src/main/java/com/example/HelloController.java (2)

14-14: Consider dependency injection for improved testability.

Direct instantiation of NtfyConnectionImpl makes it harder to test the controller in isolation. Consider injecting the connection or model via constructor/setter.

Example:

private final HelloModel model;

public HelloController() {
    this(new HelloModel(new NtfyConnectionImpl()));
}

// Package-private constructor for testing
HelloController(HelloModel model) {
    this.model = model;
}

54-61: LGTM! Proper implementation of send flow.

The method correctly handles input validation, model interaction, and UI updates. The method signature doesn't throw the declared checked exceptions, but since async operations are handled via CompletableFuture, these declarations might be unnecessary.

You could simplify the signature:

-    public void sendMessage(ActionEvent actionEvent) {
+    public void sendMessage(ActionEvent actionEvent) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72eee3b and 57f673e.

📒 Files selected for processing (4)
  • src/main/java/com/example/HelloController.java (2 hunks)
  • src/main/resources/com/example/hello-view.fxml (1 hunks)
  • src/main/resources/css/style.css (1 hunks)
  • src/test/java/com/example/HelloModelTest.java (1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/main/resources/css/style.css

[error] 6-6: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 13-13: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 14-14: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 15-15: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 15-15: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 19-19: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 20-20: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 21-21: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 22-22: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 23-23: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 24-24: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 27-27: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 28-28: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 29-29: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 30-30: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 31-31: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 32-32: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 35-35: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 36-36: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 37-37: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 38-38: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 40-40: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 41-41: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 42-42: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 43-43: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 43-43: Unexpected unknown function: dropshadow

Use a known function instead.
See MDN web docs for more details.

(lint/correctness/noUnknownFunction)


[error] 46-46: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 47-47: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 50-50: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 51-51: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 52-52: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 53-53: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 54-54: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 55-55: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)


[error] 58-58: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)

🔇 Additional comments (6)
src/test/java/com/example/HelloModelTest.java (3)

22-33: LGTM! Clean test using test double.

The test properly uses a spy to verify the message flow without external dependencies.


35-48: LGTM! Effective integration test with WireMock.

The test properly verifies the HTTP POST interaction including request body validation.


71-84: LGTM! Clean test for incoming message simulation.

The test effectively uses the spy to simulate incoming messages and verify observable list updates.

src/main/java/com/example/HelloController.java (1)

40-52: LGTM! Proper null handling in custom cell factory.

The cell factory correctly checks for both empty and null item before accessing properties.

src/main/resources/css/style.css (1)

1-59: LGTM! Valid JavaFX CSS - static analysis warnings are false positives.

The CSS uses proper JavaFX-specific properties (prefixed with -fx-) and functions like dropshadow(). The Biome linter flags these as unknown because it's designed for web CSS, not JavaFX CSS. All properties used here are valid in the JavaFX CSS specification.

src/main/resources/com/example/hello-view.fxml (1)

1-25: LGTM! Well-structured FXML layout.

The layout is clean and logically organized with proper component wiring to the controller. All fx:id attributes match the controller fields, and the onAction binding is correctly configured.

@kappsegla kappsegla closed this Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants