---
description: >-
  Tags are used to provide additional information for the request and contribute
  to a better control over deduplication. A request can only contain a unique
  tag with same name and value.
---

# Tags

There are three types of tags.

1. Case
2. Label
3. Annotation

### 1. Case

Case is a tag that is used to create a mock at a particular branching which needs to be covered in a request and does not let it get deduplicated if there is a version of the same request already present.

Case is created with the following syntax in source code.

```java
import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("case name", "case value", EnumManager.TagType.CASE);
```

Case contributes to the deduplicating hash and essentially creates a new version of the request if the latter was already present. Typically this is used to create different versions of the same request to increase code coverage and cover all branching statements.&#x20;

Case can also be added in the root context of an application. If a case is added in root context then the same case is inserted in every incoming request when the server span is created.

Case is created at root context with the following syntax in source code.&#x20;

```java
import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootCase("case name", "case value");
```

**E.g.,**&#x20;

Imagine an api where the logic splits based on a requestParam <mark style="color:blue;">`action`</mark>.&#x20;

Suppose, we hit a request with requestParam `itemType` as <mark style="color:blue;">`credit`</mark>, and then with requestParam `itemType` as <mark style="color:blue;">`debit`</mark> then the 2nd request would get deduplicated (so there won't be generation of test case for it).

To generate a test case for both the branches we can use case tag like this:

```java
@GetMapping("/updateBalance")
public ResponseEntity<?> updateBalance(@RequestParam("userId") String userId,
                                       @RequestParam("amount") BigDecimal amount,
                                       @RequestParam("action") String action) {
    // Use the CASE tag to record the branch of execution based on the action parameter.
    HypertestAgent.addTag("action", action, EnumManager.TagType.CASE);
    
    // Fetch the current balance for the user
    BigDecimal currentBalance = userService.getBalance(userId);
    
    if ("credit".equalsIgnoreCase(action)) {
         // Credit branch: add the specified amount to the current balance
         BigDecimal updatedBalance = currentBalance.add(amount);
         userService.updateBalance(userId, updatedBalance);
         return ResponseEntity.ok("User " + userId + " credited with " + amount +
                                  ". Current balance: " + updatedBalance);
    } else if ("debit".equalsIgnoreCase(action)) {
         // Debit branch: subtract the specified amount from the current balance
         BigDecimal updatedBalance = currentBalance.subtract(amount);
         userService.updateBalance(userId, updatedBalance);
         return ResponseEntity.ok("User " + userId + " debited with " + amount +
                                  ". Current balance: " + updatedBalance);
    } else {
         // Invalid action handling
         return ResponseEntity.badRequest().body("Invalid action specified.");
    }
}
```

### 2. Label

Label is a tag that is used to create a mock inside a particular route to avoid more versions of the same request due to difference in response schema. If there is a label inside a request, then only the cases and labels are considered for creating the deduplicating hash value thereby retaining the desired version of the request.

Label is created with the following syntax in source code.

```java
import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("label name", "label value", EnumManager.TagType.LABEL);
```

Label can also be added in the root context of an application. If a label is added in root context then the same label is inserted in every incoming request when the server span is created.

Label is created at root context with the following syntax in source code.&#x20;

```java
import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootLabel("label name", "label value");
```

**E.g.,**&#x20;

Imagine an endpoint that returns user details in two different response schemas based on the `detailLevel` query parameter.&#x20;

The underlying business logic remains similar, but the schema of outbound JPA call varies. Without intervention, these schema differences would result in multiple test cases.&#x20;

By adding a Label tag, you ensure that the deduplication process considers only your defined label value (e.g., a fixed output schema version), thus retaining a single desired version of the request.

```java
@GetMapping("/users")
public ResponseEntity<?> getUser(@RequestParam("detailLevel") String detailLevel) {
    // By adding a label with a constant value (e.g., "v1"),
    // we ensure that differences in the output details don't result in separate test cases.
    HypertestAgent.addTag("outputSchema", "v1", EnumManager.TagType.LABEL);
    
    if ("full".equals(detailLevel)) {
        // Full branch: returns comprehensive user details.
        User fullUser = userService.getFullUser();
        return ResponseEntity.ok(fullUser);
    } else {
        // Basic branch: returns minimal user details.
        User basicUser = userService.getBasicUser();
        return ResponseEntity.ok(basicUser);
    }
}
```

### 3. Annotation

Annotation is a tag that is used to create an unimportant mock inside a route to provide additional context to the request. This does not contribute to the deduplicating hash.

Annotation is created with the following syntax in source code.

```java
import hypertest.javaagent.HypertestAgent;
import hypertest.javaagent.bootstrap.EnumManager;

HypertestAgent.addTag("annotation name", "annotation value", EnumManager.TagType.ANNOTATION);
```

Annotation can also be added in the root context of an application. If a annotation is added in root context then the same annotation is inserted in every incoming request when the server span is created.

Annotation is created at root context with the following syntax in source code.&#x20;

```java
import hypertest.javaagent.HypertestAgent;

HypertestAgent.addRootAnnotation("label name", "label value");
```

**E.g.,**

In this scenario, there are 2 kind of APIs one for handling user operations (such as creating a user and logging in), while the other manages order-related operations.&#x20;

The annotations add metadata that can later be used on Hypertest dashboard to filter or in `.htTestConf.js`  to run only selected groups of APIs.

```java
@RestController
public class Controller {

    @PostMapping("/create")
    public ResponseEntity<?> createUser(@RequestBody User user) {
        // Annotate this endpoint as belonging to the "user" group.
        HypertestAgent.addTag("apiGroup", "user", EnumManager.TagType.ANNOTATION);
        
        // Business logic for creating a user
        userService.createUser(user);
        return ResponseEntity.ok("User created successfully");
    }

    @PostMapping("/login")
    public ResponseEntity<?> loginUser(@RequestBody LoginRequest loginRequest) {
        // Annotate this endpoint as belonging to the "user" group.
        HypertestAgent.addTag("apiGroup", "user", EnumManager.TagType.ANNOTATION);
        
        // Business logic for logging in a user
        boolean success = userService.login(loginRequest);
        if (success) {
            return ResponseEntity.ok("User logged in successfully");
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }
    }
    
    @PostMapping("/place")
    public ResponseEntity<?> placeOrder(@RequestBody Order order) {
        // Annotate this endpoint as belonging to the "order" group.
        HypertestAgent.addTag("apiGroup", "order", EnumManager.TagType.ANNOTATION);
        
        // Business logic for placing an order
        orderService.placeOrder(order);
        return ResponseEntity.ok("Order placed successfully");
    }
}
```
