Skip to content

Commit 3a80ebc

Browse files
committed
remove missleading flag
1 parent 443a56b commit 3a80ebc

6 files changed

Lines changed: 129 additions & 893 deletions

File tree

graphile/graphile-settings/__tests__/upload-resolver.e2e.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ describe('upload-resolver e2e', () => {
101101
const uploadedKeys = new Set<string>();
102102

103103
beforeAll(async () => {
104-
process.env.UPLOAD_V2_ENABLED = 'true';
105104
process.env.BUCKET_PROVIDER = 'minio';
106105
process.env.BUCKET_NAME = BUCKET;
107106
process.env.AWS_REGION = 'us-east-1';
Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
import { Readable } from 'stream';
22

3-
interface MockUploadResult {
4-
upload: { Location: string };
5-
contentType: string;
6-
}
7-
83
async function loadUploadResolverModule(opts: {
94
detectedContentType: string;
10-
uploadResultContentType?: string;
115
}) {
126
jest.resetModules();
137

14-
const mockDetectContentType = jest.fn().mockResolvedValue({
8+
const mockStreamContentType = jest.fn().mockResolvedValue({
159
stream: Readable.from([Buffer.alloc(16)]),
1610
magic: { type: opts.detectedContentType, charset: 'binary' },
1711
contentType: opts.detectedContentType,
1812
});
1913

20-
const mockUploadWithContentType = jest.fn().mockResolvedValue({
21-
upload: { Location: 'https://cdn.example.com/uploaded-file' },
22-
contentType: opts.uploadResultContentType ?? opts.detectedContentType,
23-
} as MockUploadResult);
14+
const mockUpload = jest.fn().mockResolvedValue({ etag: 'test-etag' });
15+
const mockPresignGet = jest.fn().mockResolvedValue('https://cdn.example.com/signed-url');
2416

25-
const mockUpload = jest.fn().mockResolvedValue({
26-
upload: { Location: 'https://cdn.example.com/storage-upload' },
27-
contentType: 'application/octet-stream',
28-
} as MockUploadResult);
17+
const MockS3StorageProvider = jest.fn().mockImplementation(() => ({
18+
upload: mockUpload,
19+
presignGet: mockPresignGet,
20+
}));
21+
22+
const mockPoolQuery = jest.fn().mockResolvedValue({ rows: [], rowCount: 0 });
23+
const MockPool = jest.fn().mockImplementation(() => ({
24+
query: mockPoolQuery,
25+
end: jest.fn(),
26+
}));
2927

3028
jest.doMock('@constructive-io/graphql-env', () => ({
3129
getEnvOptions: jest.fn(() => ({
@@ -40,25 +38,24 @@ async function loadUploadResolverModule(opts: {
4038
})),
4139
}));
4240

43-
jest.doMock('@constructive-io/s3-streamer', () => {
44-
const StreamerMock = jest.fn().mockImplementation(() => ({
45-
upload: mockUpload,
46-
uploadWithContentType: mockUploadWithContentType,
47-
detectContentType: mockDetectContentType,
48-
}));
49-
return {
50-
__esModule: true,
51-
default: StreamerMock,
52-
};
53-
});
41+
jest.doMock('@constructive-io/s3-streamer', () => ({
42+
__esModule: true,
43+
S3StorageProvider: MockS3StorageProvider,
44+
streamContentType: mockStreamContentType,
45+
}));
46+
47+
jest.doMock('pg', () => ({
48+
Pool: MockPool,
49+
}));
5450

5551
const mod = await import('../src/upload-resolver');
5652

5753
return {
5854
...mod,
59-
mockDetectContentType,
60-
mockUploadWithContentType,
55+
mockStreamContentType,
6156
mockUpload,
57+
mockPresignGet,
58+
mockPoolQuery,
6259
};
6360
}
6461

@@ -69,12 +66,21 @@ function makeFakeUpload(filename: string) {
6966
};
7067
}
7168

69+
function makeFakeContext(databaseId?: string, userId?: string) {
70+
return {
71+
req: {
72+
api: { databaseId },
73+
token: { user_id: userId },
74+
},
75+
};
76+
}
77+
7278
describe('uploadResolver MIME validation', () => {
7379
it('rejects disallowed MIME before uploading to storage', async () => {
7480
const {
7581
constructiveUploadFieldDefinitions,
76-
mockDetectContentType,
77-
mockUploadWithContentType,
82+
mockStreamContentType,
83+
mockUpload,
7884
} = await loadUploadResolverModule({
7985
detectedContentType: 'application/pdf',
8086
});
@@ -92,23 +98,23 @@ describe('uploadResolver MIME validation', () => {
9298
imageDef.resolve(
9399
fakeUpload as any,
94100
{},
95-
{},
101+
makeFakeContext('1'),
96102
{ uploadPlugin: { tags: {}, type: 'image' } },
97103
),
98104
).rejects.toThrow('UPLOAD_MIMETYPE');
99105

100-
expect(mockDetectContentType).toHaveBeenCalledTimes(1);
101-
expect(mockUploadWithContentType).not.toHaveBeenCalled();
106+
expect(mockStreamContentType).toHaveBeenCalledTimes(1);
107+
expect(mockUpload).not.toHaveBeenCalled();
102108
});
103109

104110
it('uploads and returns image metadata when MIME is allowed', async () => {
105111
const {
106112
constructiveUploadFieldDefinitions,
107-
mockDetectContentType,
108-
mockUploadWithContentType,
113+
mockStreamContentType,
114+
mockUpload,
115+
mockPresignGet,
109116
} = await loadUploadResolverModule({
110117
detectedContentType: 'image/png',
111-
uploadResultContentType: 'image/png',
112118
});
113119

114120
const imageDef = constructiveUploadFieldDefinitions.find(
@@ -123,21 +129,44 @@ describe('uploadResolver MIME validation', () => {
123129
const result = await imageDef.resolve(
124130
fakeUpload as any,
125131
{},
126-
{},
132+
makeFakeContext('1', 'user-123'),
127133
{ uploadPlugin: { tags: {}, type: 'image' } },
128134
);
129135

130-
expect(result).toEqual({
131-
filename: 'photo.png',
132-
mime: 'image/png',
133-
url: 'https://cdn.example.com/uploaded-file',
134-
});
135-
expect(mockDetectContentType).toHaveBeenCalledTimes(1);
136-
expect(mockUploadWithContentType).toHaveBeenCalledTimes(1);
137-
expect(mockUploadWithContentType).toHaveBeenCalledWith(
136+
expect(result).toEqual(
138137
expect.objectContaining({
139-
contentType: 'image/png',
138+
filename: 'photo.png',
139+
mime: 'image/png',
140+
url: 'https://cdn.example.com/signed-url',
141+
key: expect.stringMatching(/^1\/default\/[0-9a-f-]+_origin$/),
140142
}),
141143
);
144+
expect(mockStreamContentType).toHaveBeenCalledTimes(1);
145+
expect(mockUpload).toHaveBeenCalledTimes(1);
146+
expect(mockPresignGet).toHaveBeenCalledTimes(1);
147+
});
148+
149+
it('throws when databaseId is missing', async () => {
150+
const { constructiveUploadFieldDefinitions } = await loadUploadResolverModule({
151+
detectedContentType: 'image/png',
152+
});
153+
154+
const imageDef = constructiveUploadFieldDefinitions.find(
155+
(def) => 'name' in def && def.name === 'image',
156+
);
157+
if (!imageDef) {
158+
throw new Error('Missing image upload field definition');
159+
}
160+
161+
const fakeUpload = makeFakeUpload('photo.png');
162+
163+
await expect(
164+
imageDef.resolve(
165+
fakeUpload as any,
166+
{},
167+
{}, // no databaseId
168+
{ uploadPlugin: { tags: {}, type: 'image' } },
169+
),
170+
).rejects.toThrow('databaseId is required');
142171
});
143172
});

0 commit comments

Comments
 (0)