n8n-nodes-awx
Version:
n8n node to interact with Ansible AWX/Tower with improved type safety
292 lines • 11.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const GroupResources_1 = require("../src/resources/GroupResources");
const mockApiClient = {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
delete: jest.fn(),
};
const createMockGroup = (overrides = {}) => ({
id: 1,
type: 'group',
url: '/api/v2/groups/1/',
related: {
created_by: '/api/v2/users/1/',
modified_by: '/api/v2/users/1/',
variable_data: {},
organization: '/api/v2/organizations/1/',
hosts: '/api/v2/groups/1/hosts/',
children: '/api/v2/groups/1/children/',
potential_children: '/api/v2/groups/1/potential_children/',
all_hosts: '/api/v2/groups/1/all_hosts/',
},
summary_fields: {
inventory: {
id: 1,
name: 'Test Inventory',
description: 'Test inventory for unit testing',
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,
kind: '',
},
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 group',
name: 'Admin',
id: 1,
},
use_role: {
description: 'Can use the group in a job template',
name: 'Use',
id: 2,
},
update_role: {
description: 'May update the group',
name: 'Update',
id: 3,
},
read_role: {
description: 'May view settings for the group',
name: 'Read',
id: 4,
},
},
user_capabilities: {
edit: true,
delete: true,
copy: true,
adhoc: true,
},
},
created: '2023-01-01T00:00:00.000Z',
modified: '2023-01-01T00:00:00.000Z',
name: 'Test Group',
description: 'Test group for unit testing',
inventory: 1,
variables: '{}',
has_active_failures: false,
has_inventory_sources: false,
total_hosts: 5,
hosts_with_active_failures: 0,
total_groups: 2,
groups_with_active_failures: 0,
all_hosts: 5,
all_hosts_with_active_failures: 0,
all_groups: 2,
all_groups_with_active_failures: 0,
...overrides,
});
describe('GroupResources', () => {
let groupResources;
beforeEach(() => {
jest.clearAllMocks();
groupResources = new GroupResources_1.GroupResources(mockApiClient);
mockApiClient.get.mockImplementation((url) => {
if (url.includes('/api/v2/groups/')) {
if (url.includes('name=')) {
return Promise.resolve({
data: {
count: 1,
next: null,
previous: null,
results: [createMockGroup()]
}
});
}
else if (url.match(/\/api\/v2\/groups\/\d+\/$/)) {
return Promise.resolve({
data: createMockGroup()
});
}
return Promise.resolve({
data: {
count: 1,
next: null,
previous: null,
results: [createMockGroup()]
}
});
}
return Promise.resolve({ data: createMockGroup() });
});
mockApiClient.post.mockImplementation(() => {
return Promise.resolve({
data: createMockGroup({ id: 2, name: 'New Group' })
});
});
mockApiClient.put.mockImplementation(() => {
return Promise.resolve({
data: createMockGroup({ name: 'Updated Group' })
});
});
mockApiClient.delete.mockImplementation(() => {
return Promise.resolve();
});
});
describe('list', () => {
it('should list all groups', async () => {
const groups = await groupResources.list();
expect(Array.isArray(groups)).toBe(true);
expect(groups.length).toBeGreaterThan(0);
expect(groups[0]).toHaveProperty('id');
expect(groups[0]).toHaveProperty('name');
expect(groups[0]).toHaveProperty('inventory');
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/groups/');
});
it('should pass query parameters to the API', async () => {
const params = { inventory: 1 };
await groupResources.list(params);
expect(mockApiClient.get).toHaveBeenCalledWith(expect.stringContaining('inventory=1'));
});
});
describe('get', () => {
it('should get a group by ID', async () => {
const group = await groupResources.get(1);
expect(group).toBeDefined();
expect(group.id).toBe(1);
expect(mockApiClient.get).toHaveBeenCalledWith('/api/v2/groups/1/');
});
it('should throw an error if no ID is provided', async () => {
await expect(groupResources.get(0)).rejects.toThrow('Group ID is required');
});
});
describe('getByName', () => {
it('should get a group by name', async () => {
const group = await groupResources.getByName('Test Group');
expect(group).toBeDefined();
expect(group === null || group === void 0 ? void 0 : group.name).toBe('Test Group');
expect(mockApiClient.get).toHaveBeenCalledWith(expect.stringContaining('name=Test%20Group'));
});
it('should return null if no group is found', async () => {
mockApiClient.get.mockResolvedValueOnce({
data: {
count: 0,
results: [],
next: null,
previous: null
}
});
const group = await groupResources.getByName('Non-existent Group');
expect(group).toBeNull();
});
it('should throw an error if multiple groups with the same name are found', async () => {
mockApiClient.get.mockResolvedValueOnce({
data: {
count: 2,
results: [createMockGroup(), createMockGroup({ id: 2 })],
next: null,
previous: null
}
});
await expect(groupResources.getByName('Duplicate Group')).rejects.toThrow('Multiple groups found with name: Duplicate Group');
});
});
describe('create', () => {
it('should create a new group', async () => {
const newGroup = {
name: 'New Group',
inventory: 1,
description: 'A new test group'
};
const createdGroup = await groupResources.create(newGroup);
expect(createdGroup).toBeDefined();
expect(createdGroup.name).toBe('New Group');
expect(mockApiClient.post).toHaveBeenCalledWith('/api/v2/groups/', newGroup);
});
it('should throw an error if required fields are missing', async () => {
const invalidGroup = {};
await expect(groupResources.create(invalidGroup)).rejects.toThrow('Missing required fields: name, inventory');
});
});
describe('update', () => {
it('should update an existing group', async () => {
const updates = {
name: 'Updated Group',
description: 'Updated description'
};
const updatedGroup = await groupResources.update(1, updates);
expect(updatedGroup).toBeDefined();
expect(updatedGroup.name).toBe('Updated Group');
expect(mockApiClient.put).toHaveBeenCalledWith('/api/v2/groups/1/', updates);
});
it('should throw an error if no ID is provided', async () => {
await expect(groupResources.update(0, { name: 'Test' })).rejects.toThrow('Group ID is required');
});
});
describe('delete', () => {
it('should delete a group', async () => {
await groupResources.delete(1);
expect(mockApiClient.delete).toHaveBeenCalledWith('/api/v2/groups/1/');
});
it('should throw an error if no ID is provided', async () => {
await expect(groupResources.delete(0)).rejects.toThrow('Group ID is required');
});
});
describe('buildUrl', () => {
const testBuildUrl = (groupResources, path, params) => {
const resourcesWithPrivate = groupResources;
return resourcesWithPrivate.buildUrl(path, params);
};
it('should return the path when no params are provided', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/');
expect(result).toBe('/api/v2/groups/');
});
it('should handle empty params object', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/', {});
expect(result).toBe('/api/v2/groups/');
});
it('should handle null params', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/', null);
expect(result).toBe('/api/v2/groups/');
});
it('should append query parameters correctly', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/', {
name: 'test group',
inventory: 1,
page: 1
});
expect(result).toContain('name=test%20group');
expect(result).toContain('inventory=1');
expect(result).toContain('page=1');
expect(result).toMatch(/^\/api\/v2\/groups\/\?.*/);
});
it('should handle special characters in parameters', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/', {
search: 'group@test',
filter: 'inventory=1&name=test'
});
expect(result).toContain('search=group%40test');
expect(result).toContain('filter=inventory%3D1%26name%3Dtest');
});
it('should handle undefined and null parameter values', () => {
const result = testBuildUrl(groupResources, '/api/v2/groups/', {
name: 'test',
status: undefined,
filter: null
});
expect(result).toContain('name=test');
expect(result).not.toContain('status=');
expect(result).not.toContain('filter=');
});
});
});
//# sourceMappingURL=GroupResources.test.js.map