Hone logo
Hone
Problems

Implementing a Quarantine System with Jest

This challenge focuses on building a robust quarantine system for potentially harmful data. In real-world applications, such systems are crucial for preventing malicious inputs or configurations from affecting the core functionality of a system, ensuring stability and security. You will implement the logic for this system and then thoroughly test it using Jest.

Problem Description

You are tasked with creating a QuarantineSystem class in TypeScript. This system should be able to:

  1. Register policies: Define rules or "policies" that determine whether an item should be quarantined.
  2. Quarantine items: Based on the registered policies, decide if an incoming item should be marked for quarantine.
  3. Retrieve quarantined items: Provide a way to access all items that have been quarantined.
  4. Clear quarantine: Remove all items from the quarantine.

Key Requirements:

  • The QuarantineSystem class should accept a generic type T representing the type of items it will manage.
  • Policies should be functions that take an item of type T and return a boolean: true if the item should be quarantined, false otherwise.
  • When an item is added, it should be checked against all registered policies. If any policy returns true, the item is quarantined.
  • The system should store quarantined items in an internal data structure.
  • The system should allow for adding multiple policies.
  • The system should have a method to clear the quarantine, removing all stored items.

Expected Behavior:

  • When addItem(item) is called, the item is evaluated against all registered policies.
  • If any policy deems the item "unsafe" (returns true), the item is added to the quarantined items list.
  • Calling getQuarantinedItems() should return an array containing all items currently in quarantine.
  • Calling clearQuarantine() should empty the list of quarantined items.
  • Adding an item that is not quarantined should not change the quarantined items list.

Edge Cases to Consider:

  • Adding an item when no policies are registered.
  • Adding the same item multiple times.
  • An empty input item (if applicable to T).

Examples

Example 1:

// Policy to quarantine strings longer than 10 characters
const longStringPolicy = (item: string): boolean => item.length > 10;

// Policy to quarantine strings containing the word "danger"
const dangerWordPolicy = (item: string): boolean => item.includes("danger");

const quarantineSystem = new QuarantineSystem<string>();
quarantineSystem.addPolicy(longStringPolicy);
quarantineSystem.addPolicy(dangerWordPolicy);

quarantineSystem.addItem("short"); // Not quarantined
quarantineSystem.addItem("this is a very long string"); // Quarantined by longStringPolicy
quarantineSystem.addItem("normal string"); // Not quarantined
quarantineSystem.addItem("dangerous data"); // Quarantined by dangerWordPolicy
quarantineSystem.addItem("another long string for testing"); // Quarantined by longStringPolicy

console.log(quarantineSystem.getQuarantinedItems());
// Expected Output:
// [
//   "this is a very long string",
//   "dangerous data",
//   "another long string for testing"
// ]

Example 2:

interface UserConfig {
  id: number;
  isEnabled: boolean;
  permissions: string[];
}

// Policy to quarantine configs where isEnabled is false
const disabledConfigPolicy = (config: UserConfig): boolean => !config.isEnabled;

// Policy to quarantine configs with no permissions
const noPermissionsPolicy = (config: UserConfig): boolean => config.permissions.length === 0;

const configQuarantine = new QuarantineSystem<UserConfig>();
configQuarantine.addPolicy(disabledConfigPolicy);
configQuarantine.addPolicy(noPermissionsPolicy);

configQuarantine.addItem({ id: 1, isEnabled: true, permissions: ["read"] }); // Not quarantined
configQuarantine.addItem({ id: 2, isEnabled: false, permissions: ["write"] }); // Quarantined by disabledConfigPolicy
configQuarantine.addItem({ id: 3, isEnabled: true, permissions: [] }); // Quarantined by noPermissionsPolicy
configQuarantine.addItem({ id: 4, isEnabled: true, permissions: ["read", "write"] }); // Not quarantined

console.log(configQuarantine.getQuarantinedItems());
// Expected Output:
// [
//   { id: 2, isEnabled: false, permissions: ["write"] },
//   { id: 3, isEnabled: true, permissions: [] }
// ]

Example 3 (Clearing Quarantine):

Using the setup from Example 1:

// ... (previous setup from Example 1)

console.log(quarantineSystem.getQuarantinedItems()); // Contains 3 items
// Output:
// [
//   "this is a very long string",
//   "dangerous data",
//   "another long string for testing"
// ]

quarantineSystem.clearQuarantine();

console.log(quarantineSystem.getQuarantinedItems());
// Expected Output:
// []

Constraints

  • The QuarantineSystem class and its methods should be implemented in TypeScript.
  • You are expected to write comprehensive unit tests for your QuarantineSystem class using Jest.
  • Your tests should cover all key requirements and edge cases mentioned.
  • The QuarantineSystem should be able to handle any type T for its items.
  • There is no strict performance constraint, but your implementation should be reasonably efficient.

Notes

  • Think about how to store the registered policies. An array would be a straightforward choice.
  • Consider how to efficiently store and retrieve the quarantined items.
  • Your Jest tests should cover scenarios like:
    • Adding items that are quarantined by different policies.
    • Adding items that are not quarantined.
    • Adding duplicate items (they should be quarantined if they meet policy criteria, even if already present).
    • The behavior when no policies are added.
    • The clearQuarantine functionality.
    • Testing with different data types for T.
Loading editor...
typescript