@rooguys/sdk 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +478 -113
- package/dist/__tests__/utils/mockClient.d.ts +65 -3
- package/dist/__tests__/utils/mockClient.js +144 -5
- package/dist/errors.d.ts +123 -0
- package/dist/errors.js +163 -0
- package/dist/http-client.d.ts +167 -0
- package/dist/http-client.js +250 -0
- package/dist/index.d.ts +160 -10
- package/dist/index.js +585 -146
- package/dist/types.d.ts +372 -50
- package/dist/types.js +21 -0
- package/package.json +1 -1
- package/src/__tests__/property/request-construction.property.test.ts +142 -91
- package/src/__tests__/property/response-parsing.property.test.ts +118 -67
- package/src/__tests__/property/sdk-modules.property.test.ts +450 -0
- package/src/__tests__/unit/aha.test.ts +61 -50
- package/src/__tests__/unit/badges.test.ts +27 -33
- package/src/__tests__/unit/config.test.ts +94 -126
- package/src/__tests__/unit/errors.test.ts +106 -150
- package/src/__tests__/unit/events.test.ts +119 -144
- package/src/__tests__/unit/leaderboards.test.ts +173 -40
- package/src/__tests__/unit/levels.test.ts +25 -33
- package/src/__tests__/unit/questionnaires.test.ts +33 -42
- package/src/__tests__/unit/users.test.ts +214 -99
- package/src/__tests__/utils/mockClient.ts +193 -6
- package/src/errors.ts +255 -0
- package/src/http-client.ts +433 -0
- package/src/index.ts +742 -150
- package/src/types.ts +429 -51
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
1
|
import { Rooguys } from '../../index';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createMockRooguysClient,
|
|
4
|
+
setupMockRequest,
|
|
5
|
+
setupMockRequestError,
|
|
6
|
+
expectRequestWith,
|
|
7
|
+
MockAxiosInstance,
|
|
8
|
+
} from '../utils/mockClient';
|
|
4
9
|
import { mockResponses, mockErrors } from '../fixtures/responses';
|
|
5
10
|
|
|
6
|
-
jest.mock('axios');
|
|
7
|
-
const mockedAxios = axios as jest.Mocked<typeof axios>;
|
|
8
|
-
|
|
9
11
|
describe('Badges Resource', () => {
|
|
10
12
|
let client: Rooguys;
|
|
11
|
-
let
|
|
12
|
-
const apiKey = 'test-api-key';
|
|
13
|
+
let mockAxios: MockAxiosInstance;
|
|
13
14
|
|
|
14
15
|
beforeEach(() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
jest.clearAllMocks();
|
|
16
|
+
const mock = createMockRooguysClient();
|
|
17
|
+
client = mock.client;
|
|
18
|
+
mockAxios = mock.mockAxios;
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
describe('list', () => {
|
|
22
22
|
it('should list badges with default parameters', async () => {
|
|
23
|
-
|
|
24
|
-
mockSuccessResponse(mockResponses.badgesListResponse)
|
|
25
|
-
);
|
|
23
|
+
setupMockRequest(mockAxios, mockResponses.badgesListResponse);
|
|
26
24
|
|
|
27
25
|
const result = await client.badges.list();
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
expectRequestWith(mockAxios, {
|
|
28
|
+
method: 'GET',
|
|
29
|
+
url: '/badges',
|
|
30
30
|
params: { page: 1, limit: 50, active_only: false },
|
|
31
31
|
});
|
|
32
32
|
expect(result).toEqual(mockResponses.badgesListResponse);
|
|
@@ -34,25 +34,25 @@ describe('Badges Resource', () => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it('should list badges with custom pagination', async () => {
|
|
37
|
-
|
|
38
|
-
mockSuccessResponse(mockResponses.badgesListResponse)
|
|
39
|
-
);
|
|
37
|
+
setupMockRequest(mockAxios, mockResponses.badgesListResponse);
|
|
40
38
|
|
|
41
39
|
await client.badges.list(2, 25);
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
expectRequestWith(mockAxios, {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
url: '/badges',
|
|
44
44
|
params: { page: 2, limit: 25, active_only: false },
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('should list only active badges', async () => {
|
|
49
|
-
|
|
50
|
-
mockSuccessResponse(mockResponses.badgesListResponse)
|
|
51
|
-
);
|
|
49
|
+
setupMockRequest(mockAxios, mockResponses.badgesListResponse);
|
|
52
50
|
|
|
53
51
|
await client.badges.list(1, 50, true);
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
expectRequestWith(mockAxios, {
|
|
54
|
+
method: 'GET',
|
|
55
|
+
url: '/badges',
|
|
56
56
|
params: { page: 1, limit: 50, active_only: true },
|
|
57
57
|
});
|
|
58
58
|
});
|
|
@@ -67,7 +67,7 @@ describe('Badges Resource', () => {
|
|
|
67
67
|
totalPages: 0,
|
|
68
68
|
},
|
|
69
69
|
};
|
|
70
|
-
|
|
70
|
+
setupMockRequest(mockAxios, emptyResponse);
|
|
71
71
|
|
|
72
72
|
const result = await client.badges.list();
|
|
73
73
|
|
|
@@ -76,9 +76,7 @@ describe('Badges Resource', () => {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
it('should throw error for invalid pagination', async () => {
|
|
79
|
-
|
|
80
|
-
mockErrorResponse(400, mockErrors.invalidPaginationError.message)
|
|
81
|
-
);
|
|
79
|
+
setupMockRequestError(mockAxios, 400, 'Limit must be between 1 and 100');
|
|
82
80
|
|
|
83
81
|
await expect(client.badges.list(1, 150)).rejects.toThrow(
|
|
84
82
|
'Limit must be between 1 and 100'
|
|
@@ -86,9 +84,7 @@ describe('Badges Resource', () => {
|
|
|
86
84
|
});
|
|
87
85
|
|
|
88
86
|
it('should handle badges with all fields', async () => {
|
|
89
|
-
|
|
90
|
-
mockSuccessResponse(mockResponses.badgesListResponse)
|
|
91
|
-
);
|
|
87
|
+
setupMockRequest(mockAxios, mockResponses.badgesListResponse);
|
|
92
88
|
|
|
93
89
|
const result = await client.badges.list();
|
|
94
90
|
|
|
@@ -102,9 +98,7 @@ describe('Badges Resource', () => {
|
|
|
102
98
|
});
|
|
103
99
|
|
|
104
100
|
it('should handle server error', async () => {
|
|
105
|
-
|
|
106
|
-
mockErrorResponse(500, 'Internal server error')
|
|
107
|
-
);
|
|
101
|
+
setupMockRequestError(mockAxios, 500, 'Internal server error');
|
|
108
102
|
|
|
109
103
|
await expect(client.badges.list()).rejects.toThrow('Internal server error');
|
|
110
104
|
});
|
|
@@ -1,187 +1,155 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Rooguys } from '../../index';
|
|
3
|
-
import { createMockAxiosInstance } from '../utils/mockClient';
|
|
4
|
-
|
|
5
|
-
jest.mock('axios');
|
|
6
|
-
const mockedAxios = axios as jest.Mocked<typeof axios>;
|
|
1
|
+
import { Rooguys, ValidationError } from '../../index';
|
|
7
2
|
|
|
8
3
|
describe('SDK Configuration', () => {
|
|
9
|
-
let mockAxiosInstance: ReturnType<typeof createMockAxiosInstance>;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
mockAxiosInstance = createMockAxiosInstance();
|
|
13
|
-
mockedAxios.create.mockReturnValue(mockAxiosInstance as any);
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
4
|
describe('initialization', () => {
|
|
18
5
|
it('should initialize with API key', () => {
|
|
19
6
|
const client = new Rooguys('test-api-key');
|
|
20
|
-
|
|
21
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
22
|
-
expect.objectContaining({
|
|
23
|
-
headers: expect.objectContaining({
|
|
24
|
-
'x-api-key': 'test-api-key',
|
|
25
|
-
}),
|
|
26
|
-
})
|
|
27
|
-
);
|
|
7
|
+
expect(client.apiKey).toBe('test-api-key');
|
|
28
8
|
});
|
|
29
9
|
|
|
30
10
|
it('should use default base URL when not provided', () => {
|
|
31
|
-
new Rooguys('test-api-key');
|
|
32
|
-
|
|
33
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
34
|
-
expect.objectContaining({
|
|
35
|
-
baseURL: 'https://api.rooguys.com/v1',
|
|
36
|
-
})
|
|
37
|
-
);
|
|
11
|
+
const client = new Rooguys('test-api-key');
|
|
12
|
+
expect(client.baseUrl).toBe('https://api.rooguys.com/v1');
|
|
38
13
|
});
|
|
39
14
|
|
|
40
15
|
it('should use custom base URL when provided', () => {
|
|
41
|
-
new Rooguys('test-api-key', {
|
|
16
|
+
const client = new Rooguys('test-api-key', {
|
|
42
17
|
baseUrl: 'https://custom.api.com/v1',
|
|
43
18
|
});
|
|
44
|
-
|
|
45
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
46
|
-
expect.objectContaining({
|
|
47
|
-
baseURL: 'https://custom.api.com/v1',
|
|
48
|
-
})
|
|
49
|
-
);
|
|
19
|
+
expect(client.baseUrl).toBe('https://custom.api.com/v1');
|
|
50
20
|
});
|
|
51
21
|
|
|
52
22
|
it('should use default timeout when not provided', () => {
|
|
53
|
-
new Rooguys('test-api-key');
|
|
54
|
-
|
|
55
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
56
|
-
expect.objectContaining({
|
|
57
|
-
timeout: 10000,
|
|
58
|
-
})
|
|
59
|
-
);
|
|
23
|
+
const client = new Rooguys('test-api-key');
|
|
24
|
+
expect(client.timeout).toBe(10000);
|
|
60
25
|
});
|
|
61
26
|
|
|
62
27
|
it('should use custom timeout when provided', () => {
|
|
63
|
-
new Rooguys('test-api-key', {
|
|
28
|
+
const client = new Rooguys('test-api-key', {
|
|
64
29
|
timeout: 30000,
|
|
65
30
|
});
|
|
66
|
-
|
|
67
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
68
|
-
expect.objectContaining({
|
|
69
|
-
timeout: 30000,
|
|
70
|
-
})
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('should set Content-Type header', () => {
|
|
75
|
-
new Rooguys('test-api-key');
|
|
76
|
-
|
|
77
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
78
|
-
expect.objectContaining({
|
|
79
|
-
headers: expect.objectContaining({
|
|
80
|
-
'Content-Type': 'application/json',
|
|
81
|
-
}),
|
|
82
|
-
})
|
|
83
|
-
);
|
|
31
|
+
expect(client.timeout).toBe(30000);
|
|
84
32
|
});
|
|
85
33
|
|
|
86
34
|
it('should accept both baseUrl and timeout options', () => {
|
|
87
|
-
new Rooguys('test-api-key', {
|
|
35
|
+
const client = new Rooguys('test-api-key', {
|
|
88
36
|
baseUrl: 'https://staging.api.com/v1',
|
|
89
37
|
timeout: 20000,
|
|
90
38
|
});
|
|
91
|
-
|
|
92
|
-
expect(
|
|
93
|
-
expect.objectContaining({
|
|
94
|
-
baseURL: 'https://staging.api.com/v1',
|
|
95
|
-
timeout: 20000,
|
|
96
|
-
})
|
|
97
|
-
);
|
|
39
|
+
expect(client.baseUrl).toBe('https://staging.api.com/v1');
|
|
40
|
+
expect(client.timeout).toBe(20000);
|
|
98
41
|
});
|
|
99
42
|
|
|
100
43
|
it('should handle empty options object', () => {
|
|
101
|
-
new Rooguys('test-api-key', {});
|
|
102
|
-
|
|
103
|
-
expect(
|
|
104
|
-
expect.objectContaining({
|
|
105
|
-
baseURL: 'https://api.rooguys.com/v1',
|
|
106
|
-
timeout: 10000,
|
|
107
|
-
})
|
|
108
|
-
);
|
|
44
|
+
const client = new Rooguys('test-api-key', {});
|
|
45
|
+
expect(client.baseUrl).toBe('https://api.rooguys.com/v1');
|
|
46
|
+
expect(client.timeout).toBe(10000);
|
|
109
47
|
});
|
|
110
48
|
|
|
111
49
|
it('should handle localhost base URL', () => {
|
|
112
|
-
new Rooguys('test-api-key', {
|
|
50
|
+
const client = new Rooguys('test-api-key', {
|
|
113
51
|
baseUrl: 'http://localhost:3001/v1',
|
|
114
52
|
});
|
|
115
|
-
|
|
116
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
117
|
-
expect.objectContaining({
|
|
118
|
-
baseURL: 'http://localhost:3001/v1',
|
|
119
|
-
})
|
|
120
|
-
);
|
|
53
|
+
expect(client.baseUrl).toBe('http://localhost:3001/v1');
|
|
121
54
|
});
|
|
122
55
|
|
|
123
56
|
it('should handle very short timeout', () => {
|
|
124
|
-
new Rooguys('test-api-key', {
|
|
57
|
+
const client = new Rooguys('test-api-key', {
|
|
125
58
|
timeout: 1000,
|
|
126
59
|
});
|
|
127
|
-
|
|
128
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
129
|
-
expect.objectContaining({
|
|
130
|
-
timeout: 1000,
|
|
131
|
-
})
|
|
132
|
-
);
|
|
60
|
+
expect(client.timeout).toBe(1000);
|
|
133
61
|
});
|
|
134
62
|
|
|
135
63
|
it('should handle very long timeout', () => {
|
|
136
|
-
new Rooguys('test-api-key', {
|
|
64
|
+
const client = new Rooguys('test-api-key', {
|
|
137
65
|
timeout: 60000,
|
|
138
66
|
});
|
|
67
|
+
expect(client.timeout).toBe(60000);
|
|
68
|
+
});
|
|
139
69
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
})
|
|
144
|
-
);
|
|
70
|
+
it('should throw error when API key is missing', () => {
|
|
71
|
+
expect(() => new Rooguys('')).toThrow(ValidationError);
|
|
72
|
+
expect(() => new Rooguys('')).toThrow('API key is required');
|
|
145
73
|
});
|
|
146
74
|
});
|
|
147
75
|
|
|
148
76
|
describe('API key handling', () => {
|
|
149
|
-
it('should
|
|
150
|
-
new Rooguys('my-secret-key');
|
|
151
|
-
|
|
152
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
153
|
-
expect.objectContaining({
|
|
154
|
-
headers: expect.objectContaining({
|
|
155
|
-
'x-api-key': 'my-secret-key',
|
|
156
|
-
}),
|
|
157
|
-
})
|
|
158
|
-
);
|
|
77
|
+
it('should store API key', () => {
|
|
78
|
+
const client = new Rooguys('my-secret-key');
|
|
79
|
+
expect(client.apiKey).toBe('my-secret-key');
|
|
159
80
|
});
|
|
160
81
|
|
|
161
82
|
it('should handle long API keys', () => {
|
|
162
83
|
const longKey = 'sk_live_' + 'a'.repeat(100);
|
|
163
|
-
new Rooguys(longKey);
|
|
164
|
-
|
|
165
|
-
expect(mockedAxios.create).toHaveBeenCalledWith(
|
|
166
|
-
expect.objectContaining({
|
|
167
|
-
headers: expect.objectContaining({
|
|
168
|
-
'x-api-key': longKey,
|
|
169
|
-
}),
|
|
170
|
-
})
|
|
171
|
-
);
|
|
84
|
+
const client = new Rooguys(longKey);
|
|
85
|
+
expect(client.apiKey).toBe(longKey);
|
|
172
86
|
});
|
|
173
87
|
|
|
174
88
|
it('should handle API keys with special characters', () => {
|
|
175
89
|
const keyWithSpecialChars = 'sk_test_abc-123_XYZ.456';
|
|
176
|
-
new Rooguys(keyWithSpecialChars);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
);
|
|
90
|
+
const client = new Rooguys(keyWithSpecialChars);
|
|
91
|
+
expect(client.apiKey).toBe(keyWithSpecialChars);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('module availability', () => {
|
|
96
|
+
it('should have events module', () => {
|
|
97
|
+
const client = new Rooguys('test-api-key');
|
|
98
|
+
expect(client.events).toBeDefined();
|
|
99
|
+
expect(client.events.track).toBeDefined();
|
|
100
|
+
expect(client.events.trackBatch).toBeDefined();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should have users module', () => {
|
|
104
|
+
const client = new Rooguys('test-api-key');
|
|
105
|
+
expect(client.users).toBeDefined();
|
|
106
|
+
expect(client.users.get).toBeDefined();
|
|
107
|
+
expect(client.users.create).toBeDefined();
|
|
108
|
+
expect(client.users.update).toBeDefined();
|
|
109
|
+
expect(client.users.getBulk).toBeDefined();
|
|
110
|
+
expect(client.users.getBadges).toBeDefined();
|
|
111
|
+
expect(client.users.getRank).toBeDefined();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should have leaderboards module', () => {
|
|
115
|
+
const client = new Rooguys('test-api-key');
|
|
116
|
+
expect(client.leaderboards).toBeDefined();
|
|
117
|
+
expect(client.leaderboards.getGlobal).toBeDefined();
|
|
118
|
+
expect(client.leaderboards.list).toBeDefined();
|
|
119
|
+
expect(client.leaderboards.getCustom).toBeDefined();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should have badges module', () => {
|
|
123
|
+
const client = new Rooguys('test-api-key');
|
|
124
|
+
expect(client.badges).toBeDefined();
|
|
125
|
+
expect(client.badges.list).toBeDefined();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should have levels module', () => {
|
|
129
|
+
const client = new Rooguys('test-api-key');
|
|
130
|
+
expect(client.levels).toBeDefined();
|
|
131
|
+
expect(client.levels.list).toBeDefined();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should have questionnaires module', () => {
|
|
135
|
+
const client = new Rooguys('test-api-key');
|
|
136
|
+
expect(client.questionnaires).toBeDefined();
|
|
137
|
+
expect(client.questionnaires.get).toBeDefined();
|
|
138
|
+
expect(client.questionnaires.getActive).toBeDefined();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should have aha module', () => {
|
|
142
|
+
const client = new Rooguys('test-api-key');
|
|
143
|
+
expect(client.aha).toBeDefined();
|
|
144
|
+
expect(client.aha.declare).toBeDefined();
|
|
145
|
+
expect(client.aha.getUserScore).toBeDefined();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should have health module', () => {
|
|
149
|
+
const client = new Rooguys('test-api-key');
|
|
150
|
+
expect(client.health).toBeDefined();
|
|
151
|
+
expect(client.health.check).toBeDefined();
|
|
152
|
+
expect(client.health.isReady).toBeDefined();
|
|
185
153
|
});
|
|
186
154
|
});
|
|
187
155
|
});
|