Skip to content

Commit 1220907

Browse files
committed
Extend test coverage
1 parent af150d7 commit 1220907

13 files changed

Lines changed: 1751 additions & 10 deletions

jest.config.js

Lines changed: 131 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,137 @@ module.exports = {
2222
],
2323
coverageThreshold: {
2424
global: {
25-
branches: 15,
26-
functions: 15,
27-
lines: 25,
28-
statements: 25,
25+
branches: 45,
26+
functions: 55,
27+
lines: 60,
28+
statements: 60,
29+
},
30+
// Specific thresholds for modules with tests
31+
'src/apis/ArtifactApi.ts': {
32+
branches: 85,
33+
functions: 100,
34+
lines: 90,
35+
statements: 90,
36+
},
37+
'src/apis/DashboardApi.ts': {
38+
branches: 80,
39+
functions: 100,
40+
lines: 90,
41+
statements: 90,
42+
},
43+
'src/apis/GroupApi.ts': {
44+
branches: 80,
45+
functions: 100,
46+
lines: 90,
47+
statements: 90,
48+
},
49+
'src/apis/HealthApi.ts': {
50+
branches: 80,
51+
functions: 100,
52+
lines: 90,
53+
statements: 90,
54+
},
55+
'src/apis/LoginApi.ts': {
56+
branches: 60,
57+
functions: 100,
58+
lines: 90,
59+
statements: 90,
60+
},
61+
'src/apis/ProjectApi.ts': {
62+
branches: 80,
63+
functions: 100,
64+
lines: 90,
65+
statements: 90,
66+
},
67+
'src/apis/ResultApi.ts': {
68+
branches: 80,
69+
functions: 100,
70+
lines: 90,
71+
statements: 90,
72+
},
73+
'src/apis/RunApi.ts': {
74+
branches: 75,
75+
functions: 100,
76+
lines: 90,
77+
statements: 90,
78+
},
79+
'src/models/Artifact.ts': {
80+
branches: 80,
81+
functions: 100,
82+
lines: 90,
83+
statements: 90,
84+
},
85+
'src/models/ArtifactList.ts': {
86+
branches: 90,
87+
functions: 100,
88+
lines: 90,
89+
statements: 90,
90+
},
91+
'src/models/Dashboard.ts': {
92+
branches: 80,
93+
functions: 100,
94+
lines: 90,
95+
statements: 90,
96+
},
97+
'src/models/DashboardList.ts': {
98+
branches: 90,
99+
functions: 100,
100+
lines: 90,
101+
statements: 90,
102+
},
103+
'src/models/Group.ts': {
104+
branches: 75,
105+
functions: 100,
106+
lines: 90,
107+
statements: 90,
108+
},
109+
'src/models/GroupList.ts': {
110+
branches: 90,
111+
functions: 100,
112+
lines: 90,
113+
statements: 90,
114+
},
115+
'src/models/Pagination.ts': {
116+
branches: 90,
117+
functions: 100,
118+
lines: 90,
119+
statements: 90,
120+
},
121+
'src/models/Project.ts': {
122+
branches: 85,
123+
functions: 100,
124+
lines: 90,
125+
statements: 90,
126+
},
127+
'src/models/ProjectList.ts': {
128+
branches: 90,
129+
functions: 100,
130+
lines: 90,
131+
statements: 90,
132+
},
133+
'src/models/Result.ts': {
134+
branches: 95,
135+
functions: 100,
136+
lines: 90,
137+
statements: 90,
138+
},
139+
'src/models/ResultList.ts': {
140+
branches: 90,
141+
functions: 100,
142+
lines: 90,
143+
statements: 90,
144+
},
145+
'src/models/Run.ts': {
146+
branches: 90,
147+
functions: 100,
148+
lines: 90,
149+
statements: 90,
150+
},
151+
'src/models/RunList.ts': {
152+
branches: 90,
153+
functions: 100,
154+
lines: 90,
155+
statements: 90,
29156
},
30157
},
31158

src/apis/__tests__/ArtifactApi.test.ts

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,26 @@ describe('ArtifactApi', () => {
4545
expect(result.filename).toBe(filename);
4646
});
4747

48+
it('should require filename parameter', async () => {
49+
const fileBlob = new Blob(['data'], { type: 'text/plain' });
50+
51+
await expect(
52+
api.uploadArtifact({
53+
filename: null as unknown as string,
54+
file: fileBlob,
55+
})
56+
).rejects.toThrow();
57+
});
58+
59+
it('should require file parameter', async () => {
60+
await expect(
61+
api.uploadArtifact({
62+
filename: 'test.txt',
63+
file: null as unknown as Blob,
64+
})
65+
).rejects.toThrow();
66+
});
67+
4868
it('should attach artifact to a result', async () => {
4969
const fileBlob = new Blob(['data'], { type: 'text/plain' });
5070
const resultId = '123e4567-e89b-12d3-a456-426614174001';
@@ -405,7 +425,7 @@ describe('ArtifactApi', () => {
405425
});
406426

407427
describe('authentication', () => {
408-
it('should include Bearer token when configured', async () => {
428+
it('should include Bearer token when configured for getArtifact', async () => {
409429
const config = new Configuration({
410430
basePath: 'http://localhost/api',
411431
accessToken: async () => 'test-token-456',
@@ -437,6 +457,168 @@ describe('ArtifactApi', () => {
437457
);
438458
});
439459

460+
it('should include Bearer token when configured for uploadArtifact', async () => {
461+
const config = new Configuration({
462+
basePath: 'http://localhost/api',
463+
accessToken: async () => 'test-token-upload',
464+
});
465+
api = new ArtifactApi(config);
466+
467+
const fileBlob = new Blob(['data'], { type: 'text/plain' });
468+
const responseArtifact: Artifact = {
469+
id: '123e4567-e89b-12d3-a456-426614174000',
470+
filename: 'test.txt',
471+
};
472+
473+
mockFetch = createMockFetch(responseArtifact, 201);
474+
global.fetch = mockFetch;
475+
476+
await api.uploadArtifact({
477+
filename: 'test.txt',
478+
file: fileBlob,
479+
});
480+
481+
interface FetchOptions {
482+
method: string;
483+
headers: Record<string, string>;
484+
}
485+
expect(mockFetch).toHaveBeenCalledWith(
486+
expect.any(String),
487+
expect.objectContaining<Partial<FetchOptions>>({
488+
headers: expect.objectContaining<Record<string, string>>({
489+
Authorization: 'Bearer test-token-upload',
490+
}),
491+
})
492+
);
493+
});
494+
495+
it('should include Bearer token when configured for getArtifactList', async () => {
496+
const config = new Configuration({
497+
basePath: 'http://localhost/api',
498+
accessToken: async () => 'test-token-list',
499+
});
500+
api = new ArtifactApi(config);
501+
502+
const mockArtifactList: ArtifactList = {
503+
artifacts: [],
504+
pagination: {
505+
page: 1,
506+
pageSize: 25,
507+
totalItems: 0,
508+
totalPages: 0,
509+
},
510+
};
511+
512+
mockFetch = createMockFetch(mockArtifactList);
513+
global.fetch = mockFetch;
514+
515+
await api.getArtifactList({});
516+
517+
interface FetchOptions {
518+
method: string;
519+
headers: Record<string, string>;
520+
}
521+
expect(mockFetch).toHaveBeenCalledWith(
522+
expect.any(String),
523+
expect.objectContaining<Partial<FetchOptions>>({
524+
headers: expect.objectContaining<Record<string, string>>({
525+
Authorization: 'Bearer test-token-list',
526+
}),
527+
})
528+
);
529+
});
530+
531+
it('should include Bearer token when configured for deleteArtifact', async () => {
532+
const config = new Configuration({
533+
basePath: 'http://localhost/api',
534+
accessToken: async () => 'test-token-delete',
535+
});
536+
api = new ArtifactApi(config);
537+
538+
mockFetch = jest.fn().mockResolvedValue({
539+
ok: true,
540+
status: 204,
541+
});
542+
global.fetch = mockFetch;
543+
544+
await api.deleteArtifact({ id: '123e4567-e89b-12d3-a456-426614174000' });
545+
546+
interface FetchOptions {
547+
method: string;
548+
headers: Record<string, string>;
549+
}
550+
expect(mockFetch).toHaveBeenCalledWith(
551+
expect.any(String),
552+
expect.objectContaining<Partial<FetchOptions>>({
553+
headers: expect.objectContaining<Record<string, string>>({
554+
Authorization: 'Bearer test-token-delete',
555+
}),
556+
})
557+
);
558+
});
559+
560+
it('should include Bearer token when configured for downloadArtifact', async () => {
561+
const config = new Configuration({
562+
basePath: 'http://localhost/api',
563+
accessToken: async () => 'test-token-download',
564+
});
565+
api = new ArtifactApi(config);
566+
567+
const mockBlob = new Blob(['file content'], { type: 'text/plain' });
568+
mockFetch = jest.fn().mockResolvedValue({
569+
ok: true,
570+
status: 200,
571+
blob: async () => mockBlob,
572+
});
573+
global.fetch = mockFetch;
574+
575+
await api.downloadArtifact({ id: '123e4567-e89b-12d3-a456-426614174000' });
576+
577+
interface FetchOptions {
578+
method: string;
579+
headers: Record<string, string>;
580+
}
581+
expect(mockFetch).toHaveBeenCalledWith(
582+
expect.any(String),
583+
expect.objectContaining<Partial<FetchOptions>>({
584+
headers: expect.objectContaining<Record<string, string>>({
585+
Authorization: 'Bearer test-token-download',
586+
}),
587+
})
588+
);
589+
});
590+
591+
it('should include Bearer token when configured for viewArtifact', async () => {
592+
const config = new Configuration({
593+
basePath: 'http://localhost/api',
594+
accessToken: async () => 'test-token-view',
595+
});
596+
api = new ArtifactApi(config);
597+
598+
const mockBlob = new Blob(['<html>content</html>'], { type: 'text/html' });
599+
mockFetch = jest.fn().mockResolvedValue({
600+
ok: true,
601+
status: 200,
602+
blob: async () => mockBlob,
603+
});
604+
global.fetch = mockFetch;
605+
606+
await api.viewArtifact({ id: '123e4567-e89b-12d3-a456-426614174000' });
607+
608+
interface FetchOptions {
609+
method: string;
610+
headers: Record<string, string>;
611+
}
612+
expect(mockFetch).toHaveBeenCalledWith(
613+
expect.any(String),
614+
expect.objectContaining<Partial<FetchOptions>>({
615+
headers: expect.objectContaining<Record<string, string>>({
616+
Authorization: 'Bearer test-token-view',
617+
}),
618+
})
619+
);
620+
});
621+
440622
it('should work without authentication when not configured', async () => {
441623
const artifactId = '123e4567-e89b-12d3-a456-426614174000';
442624
const expectedArtifact: Artifact = {

0 commit comments

Comments
 (0)