@malloydata/db-publisher 0.0.315 → 0.0.316

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.
Files changed (32) hide show
  1. package/dist/client/api.d.ts +1594 -528
  2. package/dist/client/api.js +1820 -553
  3. package/dist/client/api.js.map +1 -1
  4. package/dist/client/base.d.ts +1 -1
  5. package/dist/client/base.js +1 -1
  6. package/dist/client/common.d.ts +1 -1
  7. package/dist/client/common.js +1 -1
  8. package/dist/client/configuration.d.ts +1 -1
  9. package/dist/client/configuration.js +1 -1
  10. package/dist/client/index.d.ts +1 -1
  11. package/dist/client/index.js +1 -1
  12. package/dist/publisher_connection.d.ts +4 -1
  13. package/dist/publisher_connection.integration.spec.js +208 -0
  14. package/dist/publisher_connection.integration.spec.js.map +1 -0
  15. package/dist/publisher_connection.js +42 -11
  16. package/dist/publisher_connection.js.map +1 -1
  17. package/dist/publisher_connection.unit.spec.d.ts +1 -0
  18. package/dist/{publisher_connection.spec.js → publisher_connection.unit.spec.js} +214 -175
  19. package/dist/publisher_connection.unit.spec.js.map +1 -0
  20. package/package.json +2 -2
  21. package/publisher-api-doc.yaml +1434 -449
  22. package/src/client/.openapi-generator/FILES +0 -1
  23. package/src/client/api.ts +2513 -754
  24. package/src/client/base.ts +1 -1
  25. package/src/client/common.ts +1 -1
  26. package/src/client/configuration.ts +1 -1
  27. package/src/client/index.ts +1 -1
  28. package/src/publisher_connection.integration.spec.ts +200 -0
  29. package/src/publisher_connection.ts +67 -19
  30. package/src/{publisher_connection.spec.ts → publisher_connection.unit.spec.ts} +260 -175
  31. package/dist/publisher_connection.spec.js.map +0 -1
  32. /package/dist/{publisher_connection.spec.d.ts → publisher_connection.integration.spec.d.ts} +0 -0
@@ -5,31 +5,33 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import * as malloy from '@malloydata/malloy';
9
8
  import {describeIfDatabaseAvailable} from '@malloydata/malloy/test';
10
9
  import {PublisherConnection} from './publisher_connection';
11
- import {fileURLToPath} from 'url';
12
- import * as util from 'util';
13
- import * as fs from 'fs';
14
10
  import type {ConnectionAttributes} from './client';
15
- import {Configuration, ConnectionsApi} from './client';
11
+ import {Configuration, ConnectionsApi, ConnectionsTestApi} from './client';
16
12
  import type {AxiosResponse} from 'axios';
17
13
  import type {
18
- TableSourceDef,
19
14
  SQLSourceDef,
20
15
  MalloyQueryData,
21
16
  QueryDataRow,
22
17
  } from '@malloydata/malloy';
23
18
 
24
- // mocks client code for testing
19
+ // mocks client code for testing - only for unit tests
25
20
  jest.mock('./client', () => {
26
21
  const mockConnectionsApi = {
27
22
  getConnection: jest.fn(),
28
- getTest: jest.fn(),
23
+ getTable: jest.fn(),
29
24
  getTablesource: jest.fn(),
30
25
  getSqlsource: jest.fn(),
31
26
  getQuerydata: jest.fn(),
32
27
  getTemporarytable: jest.fn(),
28
+ postSqlsource: jest.fn(),
29
+ postQuerydata: jest.fn(),
30
+ postTemporarytable: jest.fn(),
31
+ };
32
+
33
+ const mockConnectionsTestApi = {
34
+ testConnectionConfiguration: jest.fn(),
33
35
  };
34
36
 
35
37
  return {
@@ -37,6 +39,9 @@ jest.mock('./client', () => {
37
39
  basePath: 'http://test.com/api/v0',
38
40
  })),
39
41
  ConnectionsApi: jest.fn().mockImplementation(() => mockConnectionsApi),
42
+ ConnectionsTestApi: jest
43
+ .fn()
44
+ .mockImplementation(() => mockConnectionsTestApi),
40
45
  };
41
46
  });
42
47
 
@@ -46,6 +51,7 @@ describe('db:Publisher', () => {
46
51
  describe('unit', () => {
47
52
  describe('create', () => {
48
53
  let mockConnectionsApi: jest.Mocked<ConnectionsApi>;
54
+ let mockConnectionsTestApi: jest.Mocked<ConnectionsTestApi>;
49
55
  let _mockConfiguration: jest.Mocked<Configuration>;
50
56
 
51
57
  beforeEach(() => {
@@ -53,6 +59,9 @@ describe('db:Publisher', () => {
53
59
  mockConnectionsApi = new ConnectionsApi(
54
60
  new Configuration()
55
61
  ) as jest.Mocked<ConnectionsApi>;
62
+ mockConnectionsTestApi = new ConnectionsTestApi(
63
+ new Configuration()
64
+ ) as jest.Mocked<ConnectionsTestApi>;
56
65
  _mockConfiguration = new Configuration() as jest.Mocked<Configuration>;
57
66
  });
58
67
 
@@ -70,7 +79,13 @@ describe('db:Publisher', () => {
70
79
 
71
80
  const mockConnectionResponse: AxiosResponse = {
72
81
  data: {
82
+ name: 'test-connection',
83
+ type: 'bigquery',
73
84
  attributes: mockConnectionAttributes,
85
+ bigqueryConnection: {
86
+ defaultProjectId: 'test-project',
87
+ billingProjectId: 'test-project',
88
+ },
74
89
  },
75
90
  status: 200,
76
91
  statusText: 'OK',
@@ -79,7 +94,10 @@ describe('db:Publisher', () => {
79
94
  };
80
95
 
81
96
  const mockTestResponse: AxiosResponse = {
82
- data: undefined,
97
+ data: {
98
+ status: 'ok',
99
+ errorMessage: '',
100
+ },
83
101
  status: 200,
84
102
  statusText: 'OK',
85
103
  headers: {},
@@ -89,7 +107,9 @@ describe('db:Publisher', () => {
89
107
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
90
108
  mockConnectionResponse
91
109
  );
92
- mockConnectionsApi.getTest.mockResolvedValueOnce(mockTestResponse);
110
+ mockConnectionsTestApi.testConnectionConfiguration.mockResolvedValueOnce(
111
+ mockTestResponse
112
+ );
93
113
 
94
114
  const connection = await PublisherConnection.create('test-connection', {
95
115
  connectionUri:
@@ -144,7 +164,13 @@ describe('db:Publisher', () => {
144
164
 
145
165
  const mockConnectionResponse: AxiosResponse = {
146
166
  data: {
167
+ name: 'test-connection',
168
+ type: 'bigquery',
147
169
  attributes: mockConnectionAttributes,
170
+ bigqueryConnection: {
171
+ defaultProjectId: 'test-project',
172
+ billingProjectId: 'test-project',
173
+ },
148
174
  },
149
175
  status: 200,
150
176
  statusText: 'OK',
@@ -153,7 +179,10 @@ describe('db:Publisher', () => {
153
179
  };
154
180
 
155
181
  const mockTestResponse: AxiosResponse = {
156
- data: undefined,
182
+ data: {
183
+ status: 'ok',
184
+ errorMessage: '',
185
+ },
157
186
  status: 200,
158
187
  statusText: 'OK',
159
188
  headers: {},
@@ -163,7 +192,9 @@ describe('db:Publisher', () => {
163
192
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
164
193
  mockConnectionResponse
165
194
  );
166
- mockConnectionsApi.getTest.mockResolvedValueOnce(mockTestResponse);
195
+ mockConnectionsTestApi.testConnectionConfiguration.mockResolvedValueOnce(
196
+ mockTestResponse
197
+ );
167
198
 
168
199
  const connection = await PublisherConnection.create('test-connection', {
169
200
  connectionUri:
@@ -198,18 +229,6 @@ describe('db:Publisher', () => {
198
229
  });
199
230
 
200
231
  it('should fetch table schema successfully', async () => {
201
- const mockTableSchema: TableSourceDef = {
202
- type: 'table',
203
- name: 'test_table',
204
- tablePath: 'test_path',
205
- connection: 'test-connection',
206
- dialect: 'bigquery',
207
- fields: [
208
- {name: 'id', type: 'number'},
209
- {name: 'name', type: 'string'},
210
- ],
211
- };
212
-
213
232
  const mockConnectionResponse: AxiosResponse = {
214
233
  data: {
215
234
  attributes: {
@@ -227,7 +246,11 @@ describe('db:Publisher', () => {
227
246
 
228
247
  const mockTableResponse: AxiosResponse = {
229
248
  data: {
230
- source: JSON.stringify(mockTableSchema),
249
+ resource: 'test_path',
250
+ columns: [
251
+ {name: 'id', type: 'number'},
252
+ {name: 'name', type: 'string'},
253
+ ],
231
254
  },
232
255
  status: 200,
233
256
  statusText: 'OK',
@@ -238,9 +261,7 @@ describe('db:Publisher', () => {
238
261
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
239
262
  mockConnectionResponse
240
263
  );
241
- mockConnectionsApi.getTablesource.mockResolvedValueOnce(
242
- mockTableResponse
243
- );
264
+ mockConnectionsApi.getTable.mockResolvedValueOnce(mockTableResponse);
244
265
 
245
266
  const connection = await PublisherConnection.create('test-connection', {
246
267
  connectionUri:
@@ -253,11 +274,21 @@ describe('db:Publisher', () => {
253
274
  'test_path'
254
275
  );
255
276
 
256
- expect(schema).toEqual(mockTableSchema);
257
- expect(mockConnectionsApi.getTablesource).toHaveBeenCalledWith(
277
+ expect(schema).toEqual({
278
+ type: 'table',
279
+ name: 'test_key',
280
+ tablePath: 'test_path',
281
+ connection: 'test-connection',
282
+ dialect: 'bigquery',
283
+ fields: [
284
+ {name: 'id', type: 'number'},
285
+ {name: 'name', type: 'string'},
286
+ ],
287
+ });
288
+ expect(mockConnectionsApi.getTable).toHaveBeenCalledWith(
258
289
  'test-project',
259
290
  'test-connection',
260
- 'test_key',
291
+ 'test_path',
261
292
  'test_path',
262
293
  {
263
294
  headers: {
@@ -268,19 +299,59 @@ describe('db:Publisher', () => {
268
299
  });
269
300
 
270
301
  it('should handle API errors', async () => {
271
- await setupAndTestApiError(
272
- mockConnectionsApi,
273
- 'getTablesource',
274
- connection => connection.fetchTableSchema('test_key', 'test_path')
302
+ await setupAndTestApiError(mockConnectionsApi, 'getTable', connection =>
303
+ connection.fetchTableSchema('test_key', 'test_path')
275
304
  );
276
305
  });
277
306
 
278
307
  it('should handle invalid JSON response', async () => {
279
- await setupAndTestInvalidJsonResponse(
280
- mockConnectionsApi,
281
- 'getTablesource',
282
- connection => connection.fetchTableSchema('test_key', 'test_path')
308
+ const mockConnectionResponse: AxiosResponse = {
309
+ data: {
310
+ attributes: {
311
+ dialectName: 'bigquery',
312
+ isPool: false,
313
+ canPersist: true,
314
+ canStream: true,
315
+ },
316
+ },
317
+ status: 200,
318
+ statusText: 'OK',
319
+ headers: {},
320
+ config: {} as AxiosResponse['config'],
321
+ };
322
+
323
+ const mockInvalidResponse: AxiosResponse = {
324
+ data: {resource: 'invalid json', columns: null},
325
+ status: 200,
326
+ statusText: 'OK',
327
+ headers: {},
328
+ config: {} as AxiosResponse['config'],
329
+ };
330
+
331
+ mockConnectionsApi.getConnection.mockResolvedValueOnce(
332
+ mockConnectionResponse
283
333
  );
334
+ mockConnectionsApi.getTable.mockResolvedValueOnce(mockInvalidResponse);
335
+
336
+ const connection = await PublisherConnection.create('test-connection', {
337
+ connectionUri:
338
+ 'http://test.com/api/v0/projects/test-project/connections/test-connection',
339
+ accessToken: 'test-token',
340
+ });
341
+
342
+ const schema = await connection.fetchTableSchema(
343
+ 'test_key',
344
+ 'test_path'
345
+ );
346
+
347
+ expect(schema).toEqual({
348
+ type: 'table',
349
+ name: 'test_key',
350
+ tablePath: 'test_path',
351
+ connection: 'test-connection',
352
+ dialect: 'bigquery',
353
+ fields: [],
354
+ });
284
355
  });
285
356
  });
286
357
 
@@ -341,7 +412,7 @@ describe('db:Publisher', () => {
341
412
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
342
413
  mockConnectionResponse
343
414
  );
344
- mockConnectionsApi.getSqlsource.mockResolvedValueOnce(mockSqlResponse);
415
+ mockConnectionsApi.postSqlsource.mockResolvedValueOnce(mockSqlResponse);
345
416
 
346
417
  const connection = await PublisherConnection.create('test-connection', {
347
418
  connectionUri:
@@ -355,10 +426,12 @@ describe('db:Publisher', () => {
355
426
  });
356
427
 
357
428
  expect(schema).toEqual(mockSqlSchema);
358
- expect(mockConnectionsApi.getSqlsource).toHaveBeenCalledWith(
429
+ expect(mockConnectionsApi.postSqlsource).toHaveBeenCalledWith(
359
430
  'test-project',
360
431
  'test-connection',
361
- 'SELECT * FROM test_table',
432
+ {
433
+ sqlStatement: 'SELECT * FROM test_table',
434
+ },
362
435
  {
363
436
  headers: {
364
437
  Authorization: 'Bearer test-token',
@@ -370,7 +443,7 @@ describe('db:Publisher', () => {
370
443
  it('should handle API errors', async () => {
371
444
  await setupAndTestApiError(
372
445
  mockConnectionsApi,
373
- 'getSqlsource',
446
+ 'postSqlsource',
374
447
  connection =>
375
448
  connection.fetchSelectSchema({
376
449
  selectStr: 'SELECT * FROM test_table',
@@ -382,7 +455,7 @@ describe('db:Publisher', () => {
382
455
  it('should handle invalid JSON response', async () => {
383
456
  await setupAndTestInvalidJsonResponse(
384
457
  mockConnectionsApi,
385
- 'getSqlsource',
458
+ 'postSqlsource',
386
459
  connection =>
387
460
  connection.fetchSelectSchema({
388
461
  selectStr: 'SELECT * FROM test_table',
@@ -445,7 +518,7 @@ describe('db:Publisher', () => {
445
518
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
446
519
  mockConnectionResponse
447
520
  );
448
- mockConnectionsApi.getQuerydata.mockResolvedValueOnce(
521
+ mockConnectionsApi.postQuerydata.mockResolvedValueOnce(
449
522
  mockQueryResponse
450
523
  );
451
524
 
@@ -458,11 +531,11 @@ describe('db:Publisher', () => {
458
531
  const result = await connection.runSQL('SELECT * FROM test_table');
459
532
 
460
533
  expect(result).toEqual(mockQueryData);
461
- expect(mockConnectionsApi.getQuerydata).toHaveBeenCalledWith(
534
+ expect(mockConnectionsApi.postQuerydata).toHaveBeenCalledWith(
462
535
  'test-project',
463
536
  'test-connection',
464
- 'SELECT * FROM test_table',
465
- '{}',
537
+ {sqlStatement: 'SELECT * FROM test_table'},
538
+ JSON.stringify({}),
466
539
  {
467
540
  headers: {
468
541
  Authorization: 'Bearer test-token',
@@ -508,7 +581,7 @@ describe('db:Publisher', () => {
508
581
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
509
582
  mockConnectionResponse
510
583
  );
511
- mockConnectionsApi.getQuerydata.mockResolvedValueOnce(
584
+ mockConnectionsApi.postQuerydata.mockResolvedValueOnce(
512
585
  mockQueryResponse
513
586
  );
514
587
 
@@ -529,10 +602,10 @@ describe('db:Publisher', () => {
529
602
  );
530
603
 
531
604
  expect(result).toEqual(mockQueryData);
532
- expect(mockConnectionsApi.getQuerydata).toHaveBeenCalledWith(
605
+ expect(mockConnectionsApi.postQuerydata).toHaveBeenCalledWith(
533
606
  'test-project',
534
607
  'test-connection',
535
- 'SELECT * FROM test_table',
608
+ {sqlStatement: 'SELECT * FROM test_table'},
536
609
  JSON.stringify(options),
537
610
  {
538
611
  headers: {
@@ -545,7 +618,7 @@ describe('db:Publisher', () => {
545
618
  it('should handle API errors', async () => {
546
619
  await setupAndTestApiError(
547
620
  mockConnectionsApi,
548
- 'getQuerydata',
621
+ 'postQuerydata',
549
622
  connection => connection.runSQL('SELECT * FROM test_table')
550
623
  );
551
624
  });
@@ -553,7 +626,7 @@ describe('db:Publisher', () => {
553
626
  it('should handle invalid JSON response', async () => {
554
627
  await setupAndTestInvalidJsonResponse(
555
628
  mockConnectionsApi,
556
- 'getQuerydata',
629
+ 'postQuerydata',
557
630
  connection => connection.runSQL('SELECT * FROM test_table'),
558
631
  {data: 'invalid json'}
559
632
  );
@@ -613,7 +686,7 @@ describe('db:Publisher', () => {
613
686
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
614
687
  mockConnectionResponse
615
688
  );
616
- mockConnectionsApi.getQuerydata.mockResolvedValueOnce(
689
+ mockConnectionsApi.postQuerydata.mockResolvedValueOnce(
617
690
  mockQueryResponse
618
691
  );
619
692
 
@@ -631,10 +704,10 @@ describe('db:Publisher', () => {
631
704
  }
632
705
 
633
706
  expect(results).toEqual(mockQueryData.rows);
634
- expect(mockConnectionsApi.getQuerydata).toHaveBeenCalledWith(
707
+ expect(mockConnectionsApi.postQuerydata).toHaveBeenCalledWith(
635
708
  'test-project',
636
709
  'test-connection',
637
- 'SELECT * FROM test_table',
710
+ {sqlStatement: 'SELECT * FROM test_table'},
638
711
  '{}',
639
712
  {
640
713
  headers: {
@@ -681,7 +754,7 @@ describe('db:Publisher', () => {
681
754
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
682
755
  mockConnectionResponse
683
756
  );
684
- mockConnectionsApi.getQuerydata.mockResolvedValueOnce(
757
+ mockConnectionsApi.postQuerydata.mockResolvedValueOnce(
685
758
  mockQueryResponse
686
759
  );
687
760
 
@@ -707,10 +780,10 @@ describe('db:Publisher', () => {
707
780
  }
708
781
 
709
782
  expect(results).toEqual(mockQueryData.rows);
710
- expect(mockConnectionsApi.getQuerydata).toHaveBeenCalledWith(
783
+ expect(mockConnectionsApi.postQuerydata).toHaveBeenCalledWith(
711
784
  'test-project',
712
785
  'test-connection',
713
- 'SELECT * FROM test_table',
786
+ {sqlStatement: 'SELECT * FROM test_table'},
714
787
  JSON.stringify(options),
715
788
  {
716
789
  headers: {
@@ -723,7 +796,7 @@ describe('db:Publisher', () => {
723
796
  it('should handle API errors', async () => {
724
797
  await setupAndTestApiError(
725
798
  mockConnectionsApi,
726
- 'getQuerydata',
799
+ 'postQuerydata',
727
800
  async connection => {
728
801
  const stream = connection.runSQLStream('SELECT * FROM test_table');
729
802
  const results: QueryDataRow[] = [];
@@ -737,7 +810,7 @@ describe('db:Publisher', () => {
737
810
  it('should handle invalid JSON response', async () => {
738
811
  await setupAndTestInvalidJsonResponse(
739
812
  mockConnectionsApi,
740
- 'getQuerydata',
813
+ 'postQuerydata',
741
814
  async connection => {
742
815
  const stream = connection.runSQLStream('SELECT * FROM test_table');
743
816
  const results: QueryDataRow[] = [];
@@ -795,7 +868,7 @@ describe('db:Publisher', () => {
795
868
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
796
869
  mockConnectionResponse
797
870
  );
798
- mockConnectionsApi.getTemporarytable.mockResolvedValueOnce(
871
+ mockConnectionsApi.postTemporarytable.mockResolvedValueOnce(
799
872
  mockTableResponse
800
873
  );
801
874
 
@@ -810,10 +883,10 @@ describe('db:Publisher', () => {
810
883
  );
811
884
 
812
885
  expect(tableName).toBe('temp_table_123');
813
- expect(mockConnectionsApi.getTemporarytable).toHaveBeenCalledWith(
886
+ expect(mockConnectionsApi.postTemporarytable).toHaveBeenCalledWith(
814
887
  'test-project',
815
888
  'test-connection',
816
- 'SELECT * FROM test_table',
889
+ {sqlStatement: 'SELECT * FROM test_table'},
817
890
  {
818
891
  headers: {
819
892
  Authorization: 'Bearer test-token',
@@ -825,7 +898,7 @@ describe('db:Publisher', () => {
825
898
  it('should handle API errors', async () => {
826
899
  await setupAndTestApiError(
827
900
  mockConnectionsApi,
828
- 'getTemporarytable',
901
+ 'postTemporarytable',
829
902
  connection =>
830
903
  connection.manifestTemporaryTable('SELECT * FROM test_table')
831
904
  );
@@ -834,6 +907,7 @@ describe('db:Publisher', () => {
834
907
 
835
908
  describe('test', () => {
836
909
  let mockConnectionsApi: jest.Mocked<ConnectionsApi>;
910
+ let mockConnectionsTestApi: jest.Mocked<ConnectionsTestApi>;
837
911
  let _mockConfiguration: jest.Mocked<Configuration>;
838
912
 
839
913
  beforeEach(() => {
@@ -841,6 +915,9 @@ describe('db:Publisher', () => {
841
915
  mockConnectionsApi = new ConnectionsApi(
842
916
  new Configuration()
843
917
  ) as jest.Mocked<ConnectionsApi>;
918
+ mockConnectionsTestApi = new ConnectionsTestApi(
919
+ new Configuration()
920
+ ) as jest.Mocked<ConnectionsTestApi>;
844
921
  _mockConfiguration = new Configuration() as jest.Mocked<Configuration>;
845
922
  });
846
923
 
@@ -851,12 +928,18 @@ describe('db:Publisher', () => {
851
928
  it('should test connection successfully', async () => {
852
929
  const mockConnectionResponse: AxiosResponse = {
853
930
  data: {
931
+ name: 'test-connection',
932
+ type: 'bigquery',
854
933
  attributes: {
855
934
  dialectName: 'bigquery',
856
935
  isPool: false,
857
936
  canPersist: true,
858
937
  canStream: true,
859
938
  },
939
+ bigqueryConnection: {
940
+ defaultProjectId: 'test-project',
941
+ billingProjectId: 'test-project',
942
+ },
860
943
  },
861
944
  status: 200,
862
945
  statusText: 'OK',
@@ -865,7 +948,10 @@ describe('db:Publisher', () => {
865
948
  };
866
949
 
867
950
  const mockTestResponse: AxiosResponse = {
868
- data: undefined,
951
+ data: {
952
+ status: 'ok',
953
+ errorMessage: '',
954
+ },
869
955
  status: 200,
870
956
  statusText: 'OK',
871
957
  headers: {},
@@ -875,7 +961,9 @@ describe('db:Publisher', () => {
875
961
  mockConnectionsApi.getConnection.mockResolvedValueOnce(
876
962
  mockConnectionResponse
877
963
  );
878
- mockConnectionsApi.getTest.mockResolvedValueOnce(mockTestResponse);
964
+ mockConnectionsTestApi.testConnectionConfiguration.mockResolvedValueOnce(
965
+ mockTestResponse
966
+ );
879
967
 
880
968
  const connection = await PublisherConnection.create('test-connection', {
881
969
  connectionUri:
@@ -884,9 +972,23 @@ describe('db:Publisher', () => {
884
972
  });
885
973
 
886
974
  await expect(connection.test()).resolves.not.toThrow();
887
- expect(mockConnectionsApi.getTest).toHaveBeenCalledWith(
888
- 'test-project',
889
- 'test-connection',
975
+ expect(
976
+ mockConnectionsTestApi.testConnectionConfiguration
977
+ ).toHaveBeenCalledWith(
978
+ {
979
+ name: 'test-connection',
980
+ type: 'bigquery',
981
+ attributes: {
982
+ dialectName: 'bigquery',
983
+ isPool: false,
984
+ canPersist: true,
985
+ canStream: true,
986
+ },
987
+ bigqueryConnection: {
988
+ defaultProjectId: 'test-project',
989
+ billingProjectId: 'test-project',
990
+ },
991
+ },
890
992
  {
891
993
  headers: {
892
994
  Authorization: 'Bearer test-token',
@@ -895,127 +997,110 @@ describe('db:Publisher', () => {
895
997
  );
896
998
  });
897
999
  });
898
- });
899
1000
 
900
- describe.skip('integration', () => {
901
- let conn: PublisherConnection;
902
- let runtime: malloy.Runtime;
903
-
904
- beforeEach(async () => {
905
- conn = await PublisherConnection.create(
906
- 'bigquery',
907
- //{
908
- //connectionUri: 'http://localhost:4000/api/v0/projects/malloy-samples/connections/bigquery',
909
- //}
910
- {
911
- connectionUri:
912
- 'http://demo.data.pathways.localhost:8000/api/v0/projects/malloy-samples/connections/bigquery',
913
- accessToken: 'xyz',
914
- }
915
- );
916
- const files = {
917
- readURL: async (url: URL) => {
918
- const filePath = fileURLToPath(url);
919
- return await util.promisify(fs.readFile)(filePath, 'utf8');
920
- },
921
- };
922
- runtime = new malloy.Runtime({
923
- urlReader: files,
924
- connection: conn,
1001
+ describe('estimateQueryCost', () => {
1002
+ let mockConnectionsApi: jest.Mocked<ConnectionsApi>;
1003
+ let _mockConfiguration: jest.Mocked<Configuration>;
1004
+
1005
+ beforeEach(() => {
1006
+ // Get fresh instances of the mocks
1007
+ mockConnectionsApi = new ConnectionsApi(
1008
+ new Configuration()
1009
+ ) as jest.Mocked<ConnectionsApi>;
1010
+ _mockConfiguration = new Configuration() as jest.Mocked<Configuration>;
925
1011
  });
926
- });
927
1012
 
928
- afterEach(async () => {
929
- await conn.close();
930
- });
1013
+ it('should return empty object for query cost estimation', async () => {
1014
+ const mockConnectionAttributes: ConnectionAttributes = {
1015
+ dialectName: 'bigquery',
1016
+ isPool: false,
1017
+ canPersist: true,
1018
+ canStream: true,
1019
+ };
931
1020
 
932
- it('tests the connection', async () => {
933
- await conn.test();
934
- });
1021
+ const mockConnectionResponse: AxiosResponse = {
1022
+ data: {
1023
+ name: 'test-connection',
1024
+ type: 'bigquery',
1025
+ attributes: mockConnectionAttributes,
1026
+ bigqueryConnection: {
1027
+ defaultProjectId: 'test-project',
1028
+ billingProjectId: 'test-project',
1029
+ },
1030
+ },
1031
+ status: 200,
1032
+ statusText: 'OK',
1033
+ headers: {},
1034
+ config: {} as AxiosResponse['config'],
1035
+ };
935
1036
 
936
- it('correctly identifies the dialect', () => {
937
- expect(conn.dialectName).toBe('standardsql');
938
- });
1037
+ mockConnectionsApi.getConnection.mockResolvedValueOnce(
1038
+ mockConnectionResponse
1039
+ );
939
1040
 
940
- it('correctly identifies the connection as a pooled connection', () => {
941
- expect(conn.isPool()).toBe(false);
942
- });
1041
+ const connection = await PublisherConnection.create('test-connection', {
1042
+ connectionUri:
1043
+ 'http://test.com/api/v0/projects/test-project/connections/test-connection',
1044
+ accessToken: 'test-token',
1045
+ });
943
1046
 
944
- it('correctly identifies the connection as a streaming connection', () => {
945
- expect(conn.canStream()).toBe(true);
946
- });
1047
+ const cost = await connection.estimateQueryCost(
1048
+ 'SELECT * FROM test_table'
1049
+ );
947
1050
 
948
- it('correctly identifies the connection as a persistSQLResults connection', () => {
949
- expect(conn.canPersist()).toBe(true);
1051
+ expect(cost).toEqual({});
1052
+ });
950
1053
  });
951
1054
 
952
- it('fetches the table schema', async () => {
953
- const schema = await conn.fetchTableSchema(
954
- 'bigquery',
955
- 'bigquery-public-data.hacker_news.full'
956
- );
957
- expect(schema.type).toBe('table');
958
- expect(schema.dialect).toBe('standardsql');
959
- expect(schema.tablePath).toBe('bigquery-public-data.hacker_news.full');
960
- expect(schema.fields.length).toBe(14);
961
- expect(schema.fields[0].name).toBe('title');
962
- expect(schema.fields[0].type).toBe('string');
963
- });
1055
+ describe('close', () => {
1056
+ let mockConnectionsApi: jest.Mocked<ConnectionsApi>;
1057
+ let _mockConfiguration: jest.Mocked<Configuration>;
964
1058
 
965
- it('fetches the sql source schema', async () => {
966
- const schema = await conn.fetchSelectSchema({
967
- connection: 'bigquery',
968
- selectStr: 'SELECT * FROM bigquery-public-data.hacker_news.full',
1059
+ beforeEach(() => {
1060
+ // Get fresh instances of the mocks
1061
+ mockConnectionsApi = new ConnectionsApi(
1062
+ new Configuration()
1063
+ ) as jest.Mocked<ConnectionsApi>;
1064
+ _mockConfiguration = new Configuration() as jest.Mocked<Configuration>;
969
1065
  });
970
- expect(schema.type).toBe('sql_select');
971
- expect(schema.dialect).toBe('standardsql');
972
- expect(schema.fields.length).toBe(14);
973
- expect(schema.fields[0].name).toBe('title');
974
- expect(schema.fields[0].type).toBe('string');
975
- });
976
1066
 
977
- it('runs a SQL query', async () => {
978
- const res = await conn.runSQL('SELECT 1 as T');
979
- expect(res.rows[0]['T']).toBe(1);
980
- });
1067
+ it('should close connection successfully', async () => {
1068
+ const mockConnectionAttributes: ConnectionAttributes = {
1069
+ dialectName: 'bigquery',
1070
+ isPool: false,
1071
+ canPersist: true,
1072
+ canStream: true,
1073
+ };
981
1074
 
982
- it('runs a Malloy query', async () => {
983
- const sql = await runtime
984
- .loadModel(
985
- "source: stories is bigquery.table('bigquery-public-data.hacker_news.full')"
986
- )
987
- .loadQuery(
988
- 'run: stories -> { aggregate: cnt is count() group_by: `by` order_by: cnt desc limit: 10 }'
989
- )
990
- .getSQL();
991
- const res = await conn.runSQL(sql);
992
- expect(res.totalRows).toBe(10);
993
- let total = 0;
994
- for (const row of res.rows) {
995
- total += +(row['cnt'] ?? 0);
996
- }
997
- expect(total).toBe(1836679);
998
- });
1075
+ const mockConnectionResponse: AxiosResponse = {
1076
+ data: {
1077
+ name: 'test-connection',
1078
+ type: 'bigquery',
1079
+ attributes: mockConnectionAttributes,
1080
+ bigqueryConnection: {
1081
+ defaultProjectId: 'test-project',
1082
+ billingProjectId: 'test-project',
1083
+ },
1084
+ },
1085
+ status: 200,
1086
+ statusText: 'OK',
1087
+ headers: {},
1088
+ config: {} as AxiosResponse['config'],
1089
+ };
999
1090
 
1000
- it('runs a Malloy query on an sql source', async () => {
1001
- const sql = await runtime
1002
- .loadModel(
1003
- "source: stories is bigquery.sql('SELECT * FROM bigquery-public-data.hacker_news.full')"
1004
- )
1005
- .loadQuery(
1006
- 'run: stories -> { aggregate: cnt is count() group_by: `by` order_by: cnt desc limit: 20 }'
1007
- )
1008
- .getSQL();
1009
- const res = await conn.runSQL(sql);
1010
- expect(res.totalRows).toBe(20);
1011
- expect(res.rows[0]['cnt']).toBe(1346912);
1012
- });
1091
+ mockConnectionsApi.getConnection.mockResolvedValueOnce(
1092
+ mockConnectionResponse
1093
+ );
1013
1094
 
1014
- it('get temporary table name', async () => {
1015
- const sql = 'SELECT 1 as T';
1016
- const tempTableName = await conn.manifestTemporaryTable(sql);
1017
- expect(tempTableName).toBeDefined();
1018
- expect(tempTableName.startsWith('lofty-complex-452701')).toBe(true);
1095
+ const connection = await PublisherConnection.create('test-connection', {
1096
+ connectionUri:
1097
+ 'http://test.com/api/v0/projects/test-project/connections/test-connection',
1098
+ accessToken: 'test-token',
1099
+ });
1100
+
1101
+ // close() should not throw and should return void
1102
+ await expect(connection.close()).resolves.toBeUndefined();
1103
+ });
1019
1104
  });
1020
1105
  });
1021
1106
  });