Skip to content

Commit 031a5a1

Browse files
fix: outdated tests
1 parent 7fbad87 commit 031a5a1

File tree

1 file changed

+100
-111
lines changed

1 file changed

+100
-111
lines changed
Lines changed: 100 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { fetchRemoteScorecardAndPlugins } from '../remote/fetch-scorecard.js';
2-
import * as openapiCore from '@redocly/openapi-core';
2+
import * as errorUtils from '../../../utils/error.js';
33

44
describe('fetchRemoteScorecardAndPlugins', () => {
55
const mockFetch = vi.fn();
@@ -9,7 +9,9 @@ describe('fetchRemoteScorecardAndPlugins', () => {
99
beforeEach(() => {
1010
global.fetch = mockFetch;
1111
mockFetch.mockClear();
12-
vi.spyOn(openapiCore.logger, 'warn').mockImplementation(() => {});
12+
vi.spyOn(errorUtils, 'exitWithError').mockImplementation(() => {
13+
throw new Error('exitWithError called');
14+
});
1315
});
1416

1517
afterEach(() => {
@@ -20,87 +22,65 @@ describe('fetchRemoteScorecardAndPlugins', () => {
2022
await expect(fetchRemoteScorecardAndPlugins('not-a-valid-url', testToken)).rejects.toThrow();
2123
});
2224

23-
it('should return undefined when project URL pattern does not match', async () => {
24-
const result = await fetchRemoteScorecardAndPlugins(
25-
'https://example.com/invalid/path',
26-
testToken
27-
);
25+
it('should throw error when project URL pattern does not match', async () => {
26+
await expect(
27+
fetchRemoteScorecardAndPlugins('https://example.com/invalid/path', testToken)
28+
).rejects.toThrow();
2829

29-
expect(result).toBeUndefined();
30-
expect(openapiCore.logger.warn).toHaveBeenCalledWith(
30+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
3131
expect.stringContaining('Invalid project URL format')
3232
);
3333
});
3434

35-
it('should return undefined when organization is not found', async () => {
35+
it('should throw error when project is not found (404)', async () => {
3636
mockFetch.mockResolvedValueOnce({
37-
status: 200,
38-
json: async () => ({ items: [] }),
37+
status: 404,
3938
});
4039

41-
const result = await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
40+
await expect(fetchRemoteScorecardAndPlugins(validProjectUrl, testToken)).rejects.toThrow();
4241

43-
expect(result).toBeUndefined();
44-
expect(openapiCore.logger.warn).toHaveBeenCalledWith(
45-
expect.stringContaining('Organization not found')
42+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
43+
expect.stringContaining('Failed to fetch project')
4644
);
4745
});
4846

49-
it('should return undefined when organization fetch fails', async () => {
47+
it('should throw error when unauthorized (401)', async () => {
5048
mockFetch.mockResolvedValueOnce({
51-
status: 404,
49+
status: 401,
5250
});
5351

54-
const result = await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
52+
await expect(fetchRemoteScorecardAndPlugins(validProjectUrl, testToken)).rejects.toThrow();
5553

56-
expect(result).toBeUndefined();
57-
expect(openapiCore.logger.warn).toHaveBeenCalledWith(
58-
expect.stringContaining('Organization not found')
54+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
55+
expect.stringContaining('Unauthorized access to project')
5956
);
6057
});
6158

62-
it('should return undefined when project is not found', async () => {
63-
mockFetch
64-
.mockResolvedValueOnce({
65-
status: 200,
66-
json: async () => ({ items: [{ id: 'org-123', slug: 'test-org' }] }),
67-
})
68-
.mockResolvedValueOnce({
69-
status: 200,
70-
json: async () => ({ items: [] }),
71-
});
59+
it('should throw error when forbidden (403)', async () => {
60+
mockFetch.mockResolvedValueOnce({
61+
status: 403,
62+
});
7263

73-
const result = await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
64+
await expect(fetchRemoteScorecardAndPlugins(validProjectUrl, testToken)).rejects.toThrow();
7465

75-
expect(result).toBeUndefined();
76-
expect(openapiCore.logger.warn).toHaveBeenCalledWith(
77-
expect.stringContaining('Project not found')
66+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
67+
expect.stringContaining('Unauthorized access to project')
7868
);
7969
});
8070

81-
it('should return undefined when project has no scorecard config', async () => {
82-
mockFetch
83-
.mockResolvedValueOnce({
84-
status: 200,
85-
json: async () => ({ items: [{ id: 'org-123', slug: 'test-org' }] }),
86-
})
87-
.mockResolvedValueOnce({
88-
status: 200,
89-
json: async () => ({
90-
items: [
91-
{
92-
id: 'project-123',
93-
slug: 'test-project',
94-
config: {},
95-
},
96-
],
97-
}),
98-
});
71+
it('should throw error when project has no scorecard config', async () => {
72+
mockFetch.mockResolvedValueOnce({
73+
status: 200,
74+
json: async () => ({
75+
id: 'project-123',
76+
slug: 'test-project',
77+
config: {},
78+
}),
79+
});
9980

100-
const result = await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
81+
await expect(fetchRemoteScorecardAndPlugins(validProjectUrl, testToken)).rejects.toThrow();
10182

102-
expect(result).toBeUndefined();
103-
expect(openapiCore.logger.warn).toHaveBeenCalledWith(
83+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
10484
expect.stringContaining('No scorecard configuration found')
10585
);
10686
});
@@ -110,33 +90,24 @@ describe('fetchRemoteScorecardAndPlugins', () => {
11090
levels: [{ name: 'Gold', rules: {} }],
11191
};
11292

113-
mockFetch
114-
.mockResolvedValueOnce({
115-
status: 200,
116-
json: async () => ({ items: [{ id: 'org-123', slug: 'test-org' }] }),
117-
})
118-
.mockResolvedValueOnce({
119-
status: 200,
120-
json: async () => ({
121-
items: [
122-
{
123-
id: 'project-123',
124-
slug: 'test-project',
125-
config: {
126-
scorecard: mockScorecard,
127-
},
128-
},
129-
],
130-
}),
131-
});
93+
mockFetch.mockResolvedValueOnce({
94+
status: 200,
95+
json: async () => ({
96+
id: 'project-123',
97+
slug: 'test-project',
98+
config: {
99+
scorecard: mockScorecard,
100+
},
101+
}),
102+
});
132103

133104
const result = await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
134105

135106
expect(result).toEqual({
136107
scorecard: mockScorecard,
137108
plugins: undefined,
138109
});
139-
expect(openapiCore.logger.warn).not.toHaveBeenCalled();
110+
expect(errorUtils.exitWithError).not.toHaveBeenCalled();
140111
});
141112

142113
it('should return scorecard config with plugins when pluginsUrl is set', async () => {
@@ -146,23 +117,15 @@ describe('fetchRemoteScorecardAndPlugins', () => {
146117
const mockPluginsCode = 'export default [() => ({ id: "test-plugin" })]';
147118

148119
mockFetch
149-
.mockResolvedValueOnce({
150-
status: 200,
151-
json: async () => ({ items: [{ id: 'org-123', slug: 'test-org' }] }),
152-
})
153120
.mockResolvedValueOnce({
154121
status: 200,
155122
json: async () => ({
156-
items: [
157-
{
158-
id: 'project-123',
159-
slug: 'test-project',
160-
config: {
161-
scorecard: mockScorecard,
162-
pluginsUrl: 'https://example.com/plugins.js',
163-
},
164-
},
165-
],
123+
id: 'project-123',
124+
slug: 'test-project',
125+
config: {
126+
scorecard: mockScorecard,
127+
pluginsUrl: 'https://example.com/plugins.js',
128+
},
166129
}),
167130
})
168131
.mockResolvedValueOnce({
@@ -176,7 +139,7 @@ describe('fetchRemoteScorecardAndPlugins', () => {
176139
scorecard: mockScorecard,
177140
plugins: mockPluginsCode,
178141
});
179-
expect(mockFetch).toHaveBeenCalledTimes(3);
142+
expect(mockFetch).toHaveBeenCalledTimes(2);
180143
});
181144

182145
it('should return scorecard without plugins when plugin fetch fails', async () => {
@@ -185,23 +148,15 @@ describe('fetchRemoteScorecardAndPlugins', () => {
185148
};
186149

187150
mockFetch
188-
.mockResolvedValueOnce({
189-
status: 200,
190-
json: async () => ({ items: [{ id: 'org-123', slug: 'test-org' }] }),
191-
})
192151
.mockResolvedValueOnce({
193152
status: 200,
194153
json: async () => ({
195-
items: [
196-
{
197-
id: 'project-123',
198-
slug: 'test-project',
199-
config: {
200-
scorecard: mockScorecard,
201-
pluginsUrl: 'https://example.com/plugins.js',
202-
},
203-
},
204-
],
154+
id: 'project-123',
155+
slug: 'test-project',
156+
config: {
157+
scorecard: mockScorecard,
158+
pluginsUrl: 'https://example.com/plugins.js',
159+
},
205160
}),
206161
})
207162
.mockResolvedValueOnce({
@@ -216,10 +171,13 @@ describe('fetchRemoteScorecardAndPlugins', () => {
216171
});
217172
});
218173

219-
it('should use correct auth headers when fetching organization', async () => {
174+
it('should use correct auth headers with access token', async () => {
220175
mockFetch.mockResolvedValueOnce({
221176
status: 200,
222-
json: async () => ({ items: [] }),
177+
json: async () => ({
178+
id: 'project-123',
179+
config: { scorecard: { levels: [] } },
180+
}),
223181
});
224182

225183
await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
@@ -232,18 +190,49 @@ describe('fetchRemoteScorecardAndPlugins', () => {
232190
);
233191
});
234192

193+
it('should use correct auth headers with API key', async () => {
194+
const originalApiKey = process.env.REDOCLY_AUTHORIZATION;
195+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
196+
197+
mockFetch.mockResolvedValueOnce({
198+
status: 200,
199+
json: async () => ({
200+
id: 'project-123',
201+
config: { scorecard: { levels: [] } },
202+
}),
203+
});
204+
205+
await fetchRemoteScorecardAndPlugins(validProjectUrl, testToken);
206+
207+
expect(mockFetch).toHaveBeenCalledWith(
208+
expect.any(URL),
209+
expect.objectContaining({
210+
headers: { Authorization: 'Bearer test-api-key' },
211+
})
212+
);
213+
214+
// Restore original value
215+
if (originalApiKey) {
216+
process.env.REDOCLY_AUTHORIZATION = originalApiKey;
217+
} else {
218+
delete process.env.REDOCLY_AUTHORIZATION;
219+
}
220+
});
221+
235222
it('should parse project URL with different residency', async () => {
236223
const customUrl = 'https://custom.redocly.com/org/my-org/project/my-project';
237224

238225
mockFetch.mockResolvedValueOnce({
239226
status: 200,
240-
json: async () => ({ items: [] }),
227+
json: async () => ({
228+
id: 'project-123',
229+
config: { scorecard: { levels: [] } },
230+
}),
241231
});
242232

243233
await fetchRemoteScorecardAndPlugins(customUrl, testToken);
244234

245235
const callUrl = mockFetch.mock.calls[0][0].toString();
246-
expect(callUrl).toContain('https://custom.redocly.com/api/orgs');
247-
expect(callUrl).toContain('filter=slug%3Amy-org');
236+
expect(callUrl).toBe('https://custom.redocly.com/api/orgs/my-org/projects/my-project');
248237
});
249238
});

0 commit comments

Comments
 (0)