Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions spec/src/test/java/io/a2a/spec/DeviceCodeOAuthFlowTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package io.a2a.spec;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.Map;

import org.junit.jupiter.api.Test;

/**
* Unit tests for {@link DeviceCodeOAuthFlow}.
* <p>
* Tests cover construction with valid parameters, null validation of required
* fields, and handling of the optional {@code refreshUrl} field.
*
* @see DeviceCodeOAuthFlow
*/
class DeviceCodeOAuthFlowTest {

private static final String DEVICE_AUTH_URL = "https://auth.example.com/device/code";
private static final String TOKEN_URL = "https://auth.example.com/token";
private static final String REFRESH_URL = "https://auth.example.com/refresh";
private static final Map<String, String> SCOPES = Map.of("read", "Read access", "write", "Write access");

@Test
void testConstruction_withAllFields() {
DeviceCodeOAuthFlow flow = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, SCOPES);

assertEquals(DEVICE_AUTH_URL, flow.deviceAuthorizationUrl());
assertEquals(TOKEN_URL, flow.tokenUrl());
assertEquals(REFRESH_URL, flow.refreshUrl());
assertEquals(SCOPES, flow.scopes());
}

@Test
void testConstruction_withNullRefreshUrl() {
DeviceCodeOAuthFlow flow = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, null, SCOPES);

assertEquals(DEVICE_AUTH_URL, flow.deviceAuthorizationUrl());
assertEquals(TOKEN_URL, flow.tokenUrl());
assertNull(flow.refreshUrl());
assertEquals(SCOPES, flow.scopes());
}

@Test
void testConstruction_withEmptyScopes() {
DeviceCodeOAuthFlow flow = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, null, Map.of());

assertNotNull(flow.scopes());
assertEquals(0, flow.scopes().size());
Comment on lines +49 to +52
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This test only asserts properties of the scopes field. For completeness and consistency with other tests in this class (like testConstruction_withAllFields), it's better to assert the state of all fields of the constructed object. This makes the test more robust against future regressions.

        Map<String, String> emptyScopes = Map.of();
        DeviceCodeOAuthFlow flow = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, null, emptyScopes);

        assertEquals(DEVICE_AUTH_URL, flow.deviceAuthorizationUrl());
        assertEquals(TOKEN_URL, flow.tokenUrl());
        assertNull(flow.refreshUrl());
        assertEquals(emptyScopes, flow.scopes());

}

@Test
void testConstruction_nullDeviceAuthorizationUrl_throwsException() {
assertThrows(IllegalArgumentException.class,
() -> new DeviceCodeOAuthFlow(null, TOKEN_URL, REFRESH_URL, SCOPES));
}

@Test
void testConstruction_nullTokenUrl_throwsException() {
assertThrows(IllegalArgumentException.class,
() -> new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, null, REFRESH_URL, SCOPES));
}

@Test
void testConstruction_nullScopes_throwsException() {
assertThrows(IllegalArgumentException.class,
() -> new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, null));
}

@Test
void testEquality_sameValues() {
DeviceCodeOAuthFlow flow1 = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, SCOPES);
DeviceCodeOAuthFlow flow2 = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, SCOPES);

assertEquals(flow1, flow2);
assertEquals(flow1.hashCode(), flow2.hashCode());
}
Comment on lines +74 to +80
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The test for equality is good, but it only covers the case where objects are equal. To make the test suite more robust and fully validate the behavior of the record's equals and hashCode methods, it's beneficial to also include checks for inequality. I suggest renaming the test to reflect its expanded scope and adding assertions for a case where the objects are expected to be unequal.

Note: You will need to add import static org.junit.jupiter.api.Assertions.assertNotEquals; for this suggestion.

    void testEqualityAndHashCode() {
        DeviceCodeOAuthFlow flow1 = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, SCOPES);
        DeviceCodeOAuthFlow flow2 = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, REFRESH_URL, SCOPES);
        DeviceCodeOAuthFlow flow3WithNullRefresh = new DeviceCodeOAuthFlow(DEVICE_AUTH_URL, TOKEN_URL, null, SCOPES);

        // Test for equality with same values
        assertEquals(flow1, flow2);
        assertEquals(flow1.hashCode(), flow2.hashCode());

        // Test for inequality with different values
        assertNotEquals(flow1, flow3WithNullRefresh);
    }

}