Skip to content

Commit 67286d0

Browse files
committed
Create database token generation service
1 parent bf6d23c commit 67286d0

2 files changed

Lines changed: 176 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { authenticateDefaultUserInOpenOpsTables } from '@openops/common';
2+
import { DatabaseToken } from './create-database-token';
3+
import { openopsTables } from './index';
4+
5+
const TOKEN_NAME_PREFIX = 'Project_';
6+
7+
export const databaseTokenService = {
8+
async generateDatabaseToken(
9+
projectId: string,
10+
workspaceId: number,
11+
): Promise<DatabaseToken> {
12+
const { token: systemToken } =
13+
await authenticateDefaultUserInOpenOpsTables();
14+
15+
const tokenName = `${TOKEN_NAME_PREFIX}${projectId}`;
16+
17+
return openopsTables.createDatabaseToken({
18+
name: tokenName,
19+
workspaceId,
20+
systemToken,
21+
});
22+
},
23+
};
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
const openopsCommonMock = {
2+
...jest.requireActual('@openops/common'),
3+
authenticateDefaultUserInOpenOpsTables: jest.fn(),
4+
};
5+
jest.mock('@openops/common', () => openopsCommonMock);
6+
7+
const createDatabaseTokenMock = jest.fn();
8+
jest.mock('../../../src/app/openops-tables/create-database-token', () => {
9+
return { createDatabaseToken: createDatabaseTokenMock };
10+
});
11+
12+
import { DatabaseToken } from '../../../src/app/openops-tables/create-database-token';
13+
import { databaseTokenService } from '../../../src/app/openops-tables/database-token-service';
14+
15+
describe('databaseTokenService', () => {
16+
beforeEach(() => {
17+
jest.clearAllMocks();
18+
});
19+
20+
describe('generateDatabaseToken', () => {
21+
it('should generate a database token with correct name prefix and parameters', async () => {
22+
const projectId = 'test-project-123';
23+
const workspaceId = 42;
24+
const systemToken = 'test-system-token';
25+
const mockToken: DatabaseToken = {
26+
id: 1,
27+
name: 'Project_test-project-123',
28+
workspace: workspaceId,
29+
key: 'test-database-token-key',
30+
permissions: {
31+
create: true,
32+
read: true,
33+
update: true,
34+
delete: true,
35+
},
36+
};
37+
38+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue(
39+
{
40+
token: systemToken,
41+
},
42+
);
43+
createDatabaseTokenMock.mockResolvedValue(mockToken);
44+
45+
const result = await databaseTokenService.generateDatabaseToken(
46+
projectId,
47+
workspaceId,
48+
);
49+
50+
expect(result).toEqual(mockToken);
51+
expect(
52+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables,
53+
).toHaveBeenCalledTimes(1);
54+
expect(createDatabaseTokenMock).toHaveBeenCalledTimes(1);
55+
expect(createDatabaseTokenMock).toHaveBeenCalledWith({
56+
name: 'Project_test-project-123',
57+
workspaceId,
58+
systemToken,
59+
});
60+
});
61+
62+
it('should handle different project IDs correctly', async () => {
63+
const projectId = 'another-project';
64+
const workspaceId = 100;
65+
const systemToken = 'another-token';
66+
const mockToken: DatabaseToken = {
67+
id: 2,
68+
name: 'Project_another-project',
69+
workspace: workspaceId,
70+
key: 'another-key',
71+
permissions: {
72+
create: true,
73+
read: true,
74+
update: false,
75+
delete: false,
76+
},
77+
};
78+
79+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue(
80+
{
81+
token: systemToken,
82+
},
83+
);
84+
createDatabaseTokenMock.mockResolvedValue(mockToken);
85+
86+
const result = await databaseTokenService.generateDatabaseToken(
87+
projectId,
88+
workspaceId,
89+
);
90+
91+
expect(result).toEqual(mockToken);
92+
expect(createDatabaseTokenMock).toHaveBeenCalledWith({
93+
name: 'Project_another-project',
94+
workspaceId,
95+
systemToken,
96+
});
97+
});
98+
99+
it.each([
100+
{
101+
description: 'from authenticateDefaultUserInOpenOpsTables',
102+
setupMocks: (): void => {
103+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockRejectedValue(
104+
new Error('Authentication failed'),
105+
);
106+
},
107+
errorMessage: 'Authentication failed',
108+
expectedAuthCalls: 1,
109+
expectedCreateTokenCalls: 0,
110+
},
111+
{
112+
description: 'from createDatabaseToken',
113+
setupMocks: (): void => {
114+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue(
115+
{
116+
token: 'test-token',
117+
},
118+
);
119+
createDatabaseTokenMock.mockRejectedValue(
120+
new Error('Token creation failed'),
121+
);
122+
},
123+
errorMessage: 'Token creation failed',
124+
expectedAuthCalls: 1,
125+
expectedCreateTokenCalls: 1,
126+
},
127+
])(
128+
'should propagate errors $description',
129+
async ({
130+
setupMocks,
131+
errorMessage,
132+
expectedAuthCalls,
133+
expectedCreateTokenCalls,
134+
}) => {
135+
const projectId = 'test-project';
136+
const workspaceId = 1;
137+
138+
setupMocks();
139+
140+
await expect(
141+
databaseTokenService.generateDatabaseToken(projectId, workspaceId),
142+
).rejects.toThrow(errorMessage);
143+
144+
expect(
145+
openopsCommonMock.authenticateDefaultUserInOpenOpsTables,
146+
).toHaveBeenCalledTimes(expectedAuthCalls);
147+
expect(createDatabaseTokenMock).toHaveBeenCalledTimes(
148+
expectedCreateTokenCalls,
149+
);
150+
},
151+
);
152+
});
153+
});

0 commit comments

Comments
 (0)