n8n-nodes-awx
Version:
n8n node to interact with Ansible AWX/Tower with improved type safety
302 lines • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const InventoryResources_1 = require("../src/resources/InventoryResources");
const mockApiClient = {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
delete: jest.fn(),
};
jest.mock('../src/ApiClient', () => {
return jest.fn().mockImplementation(() => mockApiClient);
});
const createMockInventory = (overrides = {}) => ({
id: 1,
type: 'inventory',
url: '/api/v2/inventories/1/',
related: {
created_by: '/api/v2/users/1/',
modified_by: '/api/v2/users/1/',
organization: '/api/v2/organizations/1/',
inventory_sources: '/api/v2/inventories/1/inventory_sources/',
groups: '/api/v2/inventories/1/groups/',
hosts: '/api/v2/inventories/1/hosts/',
root_groups: '/api/v2/inventories/1/root_groups/',
variable_data: {},
},
summary_fields: {
organization: {
id: 1,
name: 'Default',
description: ''
},
created_by: {
id: 1,
username: 'admin',
first_name: '',
last_name: ''
},
modified_by: {
id: 1,
username: 'admin',
first_name: '',
last_name: ''
},
object_roles: {
admin_role: {
description: 'Can manage all aspects of the inventory',
name: 'Admin',
id: 1
},
update_role: {
description: 'May update the inventory',
name: 'Update',
id: 2
},
adhoc_role: {
description: 'May run arbitrary commands against the inventory',
name: 'Ad Hoc',
id: 3
},
use_role: {
description: 'Can use the inventory in a job template',
name: 'Use',
id: 4
},
read_role: {
description: 'May view settings for the inventory',
name: 'Read',
id: 5
},
},
user_capabilities: {
edit: true,
delete: true,
copy: true,
adhoc: true
},
groups: {
count: 3,
results: [
{ id: 1, name: 'web-servers', url: '/api/v2/groups/1/' },
{ id: 2, name: 'db-servers', url: '/api/v2/groups/2/' },
{ id: 3, name: 'app-servers', url: '/api/v2/groups/3/' },
]
},
total_hosts: 10,
hosts_with_active_failures: 0,
total_groups: 3,
has_inventory_sources: false,
total_inventory_sources: 0,
inventory_sources_with_failures: 0,
organization_id: 1,
kind: ''
},
name: 'Test Inventory',
description: 'Test inventory for unit testing',
organization: 1,
kind: '',
host_filter: null,
variables: '{}',
has_active_failures: false,
total_hosts: 10,
hosts_with_active_failures: 0,
total_groups: 3,
has_inventory_sources: false,
total_inventory_sources: 0,
inventory_sources_with_failures: 0,
organization_id: 1,
created: '2023-01-01T00:00:00.000Z',
modified: '2023-01-01T00:00:00.000Z',
...overrides
});
describe('InventoryResources', () => {
let inventoryResources;
beforeEach(() => {
jest.clearAllMocks();
inventoryResources = new InventoryResources_1.InventoryResources(mockApiClient);
mockApiClient.get.mockImplementation((url) => {
if (url.includes('/api/v2/inventories/')) {
if (url.includes('name=')) {
return Promise.resolve({
data: {
count: 1,
next: null,
previous: null,
results: [createMockInventory()]
}
});
}
else if (url.match(/\/api\/v2\/inventories\/\d+\/$/)) {
return Promise.resolve({
data: createMockInventory()
});
}
return Promise.resolve({
data: {
count: 1,
next: null,
previous: null,
results: [createMockInventory()]
}
});
}
return Promise.resolve({ data: createMockInventory() });
});
mockApiClient.post.mockImplementation(() => {
return Promise.resolve({
data: createMockInventory()
});
});
mockApiClient.put.mockImplementation(() => {
return Promise.resolve({
data: createMockInventory({ name: 'Updated Test Inventory' })
});
});
mockApiClient.delete.mockImplementation(() => {
return Promise.resolve();
});
});
describe('list', () => {
it('should list all inventories', async () => {
const inventories = await inventoryResources.list();
expect(Array.isArray(inventories)).toBe(true);
expect(inventories.length).toBeGreaterThan(0);
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/inventories/');
});
it('should pass query parameters when provided', async () => {
const params = { name: 'Test Inventory' };
await inventoryResources.list(params);
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/inventories/?name=Test%20Inventory');
});
});
describe('get', () => {
it('should get an inventory by ID', async () => {
const inventory = await inventoryResources.get(1);
expect(inventory).toBeDefined();
expect(inventory.id).toBe(1);
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/inventories/1/');
});
it('should throw an error when ID is not provided', async () => {
await expect(inventoryResources.get(null)).rejects.toThrow('Inventory ID is required');
});
});
describe('getByName', () => {
it('should get an inventory by name', async () => {
const inventory = await inventoryResources.getByName('Test Inventory');
expect(inventory).toBeDefined();
expect(inventory === null || inventory === void 0 ? void 0 : inventory.name).toBe('Test Inventory');
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/inventories/?name=Test%20Inventory');
});
it('should return null when no inventory is found', async () => {
mockApiClient.get.mockResolvedValueOnce({
data: {
count: 0,
results: []
}
});
const inventory = await inventoryResources.getByName('Non-existent Inventory');
expect(inventory).toBeNull();
});
it('should throw an error when multiple inventories with the same name are found', async () => {
mockApiClient.get.mockResolvedValueOnce({
data: {
count: 2,
results: [
createMockInventory({ id: 1, name: 'Duplicate' }),
createMockInventory({ id: 2, name: 'Duplicate' })
]
}
});
await expect(inventoryResources.getByName('Duplicate')).rejects.toThrow('Multiple inventories found with name: Duplicate');
});
});
describe('create', () => {
it('should create a new inventory', async () => {
const newInventory = {
name: 'New Test Inventory',
organization: 1,
description: 'A new test inventory'
};
const inventory = await inventoryResources.create(newInventory);
expect(inventory).toBeDefined();
expect(mockApiClient.post).toHaveBeenCalledWith('/api/v2/inventories/', newInventory);
});
it('should throw an error when required fields are missing', async () => {
const emptyInventory = {};
await expect(inventoryResources.create(emptyInventory)).rejects.toThrow('Missing required fields: name, organization');
});
});
describe('update', () => {
it('should update an existing inventory', async () => {
const updates = {
name: 'Updated Test Inventory',
description: 'Updated description'
};
const inventory = await inventoryResources.update(1, updates);
expect(inventory).toBeDefined();
expect(inventory.name).toBe('Updated Test Inventory');
expect(mockApiClient.put).toHaveBeenCalledWith('/api/v2/inventories/1/', updates);
});
it('should throw an error when ID is not provided', async () => {
await expect(inventoryResources.update(null, { name: 'Test' })).rejects.toThrow('Inventory ID is required');
});
});
describe('delete', () => {
it('should delete an inventory', async () => {
await inventoryResources.delete(1);
expect(mockApiClient.delete).toHaveBeenCalledWith('/api/v2/inventories/1/');
});
it('should throw an error when ID is not provided', async () => {
await expect(inventoryResources.delete(null)).rejects.toThrow('Inventory ID is required');
});
});
describe('buildUrl', () => {
const testBuildUrl = (inventoryResources, path, params) => {
const resourcesWithPrivate = inventoryResources;
return resourcesWithPrivate.buildUrl(path, params);
};
it('should return the path when no params are provided', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/');
expect(result).toBe('/api/v2/inventories/');
});
it('should handle empty params object', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/', {});
expect(result).toBe('/api/v2/inventories/');
});
it('should handle null params', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/', null);
expect(result).toBe('/api/v2/inventories/');
});
it('should append query parameters correctly', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/', {
name: 'test inventory',
organization: 1,
page: 1
});
expect(result).toContain('name=test%20inventory');
expect(result).toContain('organization=1');
expect(result).toContain('page=1');
expect(result).toMatch(/^\/api\/v2\/inventories\/\?.*/);
});
it('should handle special characters in parameters', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/', {
search: 'inventory@test',
filter: 'organization=1&name=test'
});
expect(result).toContain('search=inventory%40test');
expect(result).toContain('filter=organization%3D1%26name%3Dtest');
});
it('should handle undefined and null parameter values', () => {
const result = testBuildUrl(inventoryResources, '/api/v2/inventories/', {
name: 'test',
status: undefined,
filter: null
});
expect(result).toContain('name=test');
expect(result).not.toContain('status=');
expect(result).not.toContain('filter=');
});
});
});
//# sourceMappingURL=InventoryResources.test.js.map