|
| 1 | +import { PostgisAggregatePlugin } from '../src/plugins/aggregate-functions'; |
| 2 | + |
| 3 | +interface MockExtensionInfo { |
| 4 | + schemaName: string; |
| 5 | + geometryCodec: { name: string }; |
| 6 | + geographyCodec: { name: string } | null; |
| 7 | +} |
| 8 | + |
| 9 | +interface MockBuild { |
| 10 | + pgGISExtensionInfo: MockExtensionInfo | undefined; |
| 11 | + extend?(base: Record<string, unknown>, extra: Record<string, unknown>, reason: string): Record<string, unknown>; |
| 12 | +} |
| 13 | + |
| 14 | +function createMockBuild(schemaName = 'public', hasPostgis = true): MockBuild { |
| 15 | + return { |
| 16 | + pgGISExtensionInfo: hasPostgis |
| 17 | + ? { |
| 18 | + schemaName, |
| 19 | + geometryCodec: { name: 'geometry' }, |
| 20 | + geographyCodec: null |
| 21 | + } |
| 22 | + : undefined, |
| 23 | + extend(base: Record<string, unknown>, extra: Record<string, unknown>, _reason: string) { |
| 24 | + return { ...base, ...extra }; |
| 25 | + } |
| 26 | + }; |
| 27 | +} |
| 28 | + |
| 29 | +describe('PostgisAggregatePlugin', () => { |
| 30 | + describe('plugin metadata', () => { |
| 31 | + it('should have correct name', () => { |
| 32 | + expect(PostgisAggregatePlugin.name).toBe('PostgisAggregatePlugin'); |
| 33 | + }); |
| 34 | + |
| 35 | + it('should have correct version', () => { |
| 36 | + expect(PostgisAggregatePlugin.version).toBe('1.0.0'); |
| 37 | + }); |
| 38 | + |
| 39 | + it('should declare after dependencies', () => { |
| 40 | + expect(PostgisAggregatePlugin.after).toContain('PostgisRegisterTypesPlugin'); |
| 41 | + expect(PostgisAggregatePlugin.after).toContain('PostgisExtensionDetectionPlugin'); |
| 42 | + }); |
| 43 | + }); |
| 44 | + |
| 45 | + describe('build hook', () => { |
| 46 | + const buildHook = (PostgisAggregatePlugin as any).schema.hooks.build; |
| 47 | + |
| 48 | + it('should return build unchanged when PostGIS is not available', () => { |
| 49 | + const build = createMockBuild('public', false); |
| 50 | + const result = buildHook(build); |
| 51 | + expect(result).toBe(build); |
| 52 | + expect(result.pgGISAggregateFunctions).toBeUndefined(); |
| 53 | + }); |
| 54 | + |
| 55 | + it('should add pgGISAggregateFunctions to build when PostGIS is available', () => { |
| 56 | + const build = createMockBuild(); |
| 57 | + const result = buildHook(build); |
| 58 | + expect(result.pgGISAggregateFunctions).toBeDefined(); |
| 59 | + }); |
| 60 | + |
| 61 | + it('should define stExtent aggregate function', () => { |
| 62 | + const result = buildHook(createMockBuild()); |
| 63 | + const { stExtent } = result.pgGISAggregateFunctions; |
| 64 | + expect(stExtent).toBeDefined(); |
| 65 | + expect(stExtent.sqlFunction).toBe('public.st_extent'); |
| 66 | + expect(stExtent.returnsGeometry).toBe(true); |
| 67 | + expect(stExtent.description).toContain('Bounding box'); |
| 68 | + }); |
| 69 | + |
| 70 | + it('should define stUnion aggregate function', () => { |
| 71 | + const result = buildHook(createMockBuild()); |
| 72 | + const { stUnion } = result.pgGISAggregateFunctions; |
| 73 | + expect(stUnion).toBeDefined(); |
| 74 | + expect(stUnion.sqlFunction).toBe('public.st_union'); |
| 75 | + expect(stUnion.returnsGeometry).toBe(true); |
| 76 | + }); |
| 77 | + |
| 78 | + it('should define stCollect aggregate function', () => { |
| 79 | + const result = buildHook(createMockBuild()); |
| 80 | + const { stCollect } = result.pgGISAggregateFunctions; |
| 81 | + expect(stCollect).toBeDefined(); |
| 82 | + expect(stCollect.sqlFunction).toBe('public.st_collect'); |
| 83 | + expect(stCollect.returnsGeometry).toBe(true); |
| 84 | + }); |
| 85 | + |
| 86 | + it('should define stConvexHull aggregate function with requiresCollect flag', () => { |
| 87 | + const result = buildHook(createMockBuild()); |
| 88 | + const { stConvexHull } = result.pgGISAggregateFunctions; |
| 89 | + expect(stConvexHull).toBeDefined(); |
| 90 | + expect(stConvexHull.sqlFunction).toBe('public.st_convexhull'); |
| 91 | + expect(stConvexHull.returnsGeometry).toBe(true); |
| 92 | + expect(stConvexHull.requiresCollect).toBe(true); |
| 93 | + }); |
| 94 | + |
| 95 | + it('should use the correct schema name', () => { |
| 96 | + const result = buildHook(createMockBuild('postgis_ext')); |
| 97 | + expect(result.pgGISAggregateFunctions.stExtent.sqlFunction).toBe('postgis_ext.st_extent'); |
| 98 | + expect(result.pgGISAggregateFunctions.stUnion.sqlFunction).toBe('postgis_ext.st_union'); |
| 99 | + expect(result.pgGISAggregateFunctions.stCollect.sqlFunction).toBe('postgis_ext.st_collect'); |
| 100 | + expect(result.pgGISAggregateFunctions.stConvexHull.sqlFunction).toBe('postgis_ext.st_convexhull'); |
| 101 | + }); |
| 102 | + |
| 103 | + it('should define exactly 4 aggregate functions', () => { |
| 104 | + const result = buildHook(createMockBuild()); |
| 105 | + expect(Object.keys(result.pgGISAggregateFunctions)).toHaveLength(4); |
| 106 | + }); |
| 107 | + }); |
| 108 | +}); |
0 commit comments