Skip to content

Commit a4458ff

Browse files
committed
throw WriteError if signedUrl is missing, reset fetch method in test
1 parent d497b2b commit a4458ff

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

src/access/infra/repositories/AccessRepository.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export class AccessRepository extends ApiRepository implements IAccessRepository
9999
throw new WriteError(this.buildFetchErrorMessage(response.status, responseData))
100100
}
101101

102-
return responseData.data.signedUrl as string
102+
return this.getSignedUrlOrThrow(responseData)
103103
}
104104

105105
private getFetchCredentials(withCredentials?: boolean): RequestCredentials | undefined {
@@ -149,7 +149,13 @@ export class AccessRepository extends ApiRepository implements IAccessRepository
149149
return await response.json()
150150
}
151151

152-
return await response.text()
152+
const responseText = await response.text()
153+
154+
try {
155+
return JSON.parse(responseText)
156+
} catch {
157+
return responseText
158+
}
153159
}
154160

155161
private buildFetchErrorMessage(status: number, responseData: any): string {
@@ -160,4 +166,14 @@ export class AccessRepository extends ApiRepository implements IAccessRepository
160166

161167
return `[${status}] ${message}`
162168
}
169+
170+
private getSignedUrlOrThrow(responseData: any): string {
171+
const signedUrl = responseData?.data?.signedUrl
172+
173+
if (typeof signedUrl !== 'string' || signedUrl.length === 0) {
174+
throw new WriteError('Missing signedUrl in access download response.')
175+
}
176+
177+
return signedUrl
178+
}
163179
}

test/unit/access/AccessRepository.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import { AccessRepository } from '../../../src/access/infra/repositories/AccessRepository'
66
import { GuestbookResponseDTO } from '../../../src/access/domain/dtos/GuestbookResponseDTO'
7+
import { WriteError } from '../../../src/core/domain/repositories/WriteError'
78
import {
89
ApiConfig,
910
DataverseApiAuthMechanism
@@ -12,6 +13,7 @@ import { TestConstants } from '../../testHelpers/TestConstants'
1213

1314
describe('AccessRepository', () => {
1415
const sut = new AccessRepository()
16+
const originalFetch = global.fetch
1517
const guestbookResponse: GuestbookResponseDTO = {
1618
guestbookResponse: {
1719
answers: [{ id: 1, value: 'question 1' }]
@@ -26,6 +28,7 @@ describe('AccessRepository', () => {
2628
})
2729

2830
afterEach(() => {
31+
global.fetch = originalFetch
2932
window.localStorage.clear()
3033
})
3134

@@ -66,4 +69,52 @@ describe('AccessRepository', () => {
6669
)
6770
expect(actual).toBe('https://signed.dataset')
6871
})
72+
73+
test('parses signed url from a JSON body when content-type is incorrect', async () => {
74+
ApiConfig.init(
75+
TestConstants.TEST_API_URL,
76+
DataverseApiAuthMechanism.BEARER_TOKEN,
77+
undefined,
78+
TestConstants.TEST_BEARER_TOKEN_LOCAL_STORAGE_KEY
79+
)
80+
81+
const fetchMock = jest.fn().mockResolvedValue({
82+
ok: true,
83+
status: 200,
84+
headers: new Headers({ 'content-type': 'text/plain' }),
85+
text: jest
86+
.fn()
87+
.mockResolvedValue(JSON.stringify({ data: { signedUrl: 'https://signed.text' } }))
88+
} as unknown as Response)
89+
90+
global.fetch = fetchMock as typeof fetch
91+
92+
await expect(sut.submitGuestbookForDatasetDownload(123, guestbookResponse)).resolves.toBe(
93+
'https://signed.text'
94+
)
95+
})
96+
97+
test('throws WriteError when signedUrl is missing from a successful response', async () => {
98+
ApiConfig.init(
99+
TestConstants.TEST_API_URL,
100+
DataverseApiAuthMechanism.BEARER_TOKEN,
101+
undefined,
102+
TestConstants.TEST_BEARER_TOKEN_LOCAL_STORAGE_KEY
103+
)
104+
105+
const fetchMock = jest.fn().mockResolvedValue({
106+
ok: true,
107+
status: 200,
108+
headers: new Headers({ 'content-type': 'application/json' }),
109+
json: jest.fn().mockResolvedValue({
110+
data: {}
111+
})
112+
} as unknown as Response)
113+
114+
global.fetch = fetchMock as typeof fetch
115+
116+
await expect(sut.submitGuestbookForDatasetDownload(123, guestbookResponse)).rejects.toThrow(
117+
new WriteError('Missing signedUrl in access download response.')
118+
)
119+
})
69120
})

0 commit comments

Comments
 (0)