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:
- Register policies: Define rules or "policies" that determine whether an item should be quarantined.
- Quarantine items: Based on the registered policies, decide if an incoming item should be marked for quarantine.
- Retrieve quarantined items: Provide a way to access all items that have been quarantined.
- Clear quarantine: Remove all items from the quarantine.
Key Requirements:
- The
QuarantineSystemclass should accept a generic typeTrepresenting the type of items it will manage. - Policies should be functions that take an item of type
Tand return a boolean:trueif the item should be quarantined,falseotherwise. - 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
QuarantineSystemclass and its methods should be implemented in TypeScript. - You are expected to write comprehensive unit tests for your
QuarantineSystemclass using Jest. - Your tests should cover all key requirements and edge cases mentioned.
- The
QuarantineSystemshould be able to handle any typeTfor 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
clearQuarantinefunctionality. - Testing with different data types for
T.