Files
windmill/frontend/src/lib/components/dbt/projectFiles.test.ts
T
baefa1345b feat: give dbt its own editor with an explicitly refreshed model graph (#10448)
* feat: give dbt its own editor with an explicitly refreshed model graph

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: bump ee ref for the agent-worker dbt editor graph

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: scope editor graph retention by principal, carry parse context, honor nlang

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: bump ee ref

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep the dbt editor's model graph and log panel mounted across tabs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep the dbt_edge to dbt_node joins on an index-usable equality

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: poll a parse until the job ends, resolve the project key, correct the docs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: surface a slow parse's job, bound poll failures, drop banned bindable defaults

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: hide the dbt Generated UI content, not only its tab

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: honor disabled Triggers in the dbt tab fallback, record permissioned_as

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: one dbt pane with the run drawn on the models, and a full-height script graph

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: move the dbt build arguments behind the Build button

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: trim the dbt editor toolbar and stop the graph asserting a cause it lacks

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: mark dbt as alpha in the language picker and announce it once

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: trim the dbt alpha notice

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: give a selected dbt model the whole detail section, with a close that deselects

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: close the dbt detail panel by clicking away, and make its close obvious

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: cache the agent-worker dbt query, which needs the private feature to compile

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: never fall back to a settings tab the embedder disabled

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: preview dbt rows from the same project the graph was parsed from

* feat: hide the script-kind selector for dbt projects

* fix: pin a dbt row preview to the project its graph was parsed from

* fix: pin a dbt row preview to the arguments its graph was parsed under

* fix: keep dbt preview placeholders live while its vars stay pinned

* fix: report a warehouse-less dbt parse's counts and flag stale preview args

* fix: tell the pinned-vars case apart from a stale placeholder

* chore: update ee-repo-ref to 59044635769f18f8ff5073236cfc7b5f41e917cc

This commit updates the EE repository reference after PR #707 was merged in windmill-ee-private.

Previous ee-repo-ref: 7e424384cdd4cef8653b55b04f17ad3f801bc50c

New ee-repo-ref: 59044635769f18f8ff5073236cfc7b5f41e917cc

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-08-03 03:32:08 +02:00

73 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import type { ScriptModule } from '$lib/gen'
import { dbtModelSelector, dbtModulePath, dbtProjectFileKey } from './projectFiles'
const mod = (content: string): ScriptModule => ({ content, language: 'dbt' as any })
const PROJECT = `name: jaffle
model-paths: ["models"]
`
describe('dbtModulePath', () => {
// The worker resolves `.` and `//` away when it materialises the bundle, so a
// redundant spelling is a second key for one file on disk and walks straight
// past a check that compares the typed string.
it('canonicalises before the reserved-name and duplicate checks', () => {
expect(dbtModulePath('./models//x.sql', {})).toEqual({ path: 'models/x.sql' })
expect(dbtModulePath('./wm_dbt.yaml', {})).toEqual({
error: expect.stringContaining('is the descriptor')
})
const bundle = { './models/x.sql': mod('select 1') }
expect(dbtModulePath('models/x.sql', bundle)).toEqual({
error: expect.stringContaining('./models/x.sql already exists')
})
})
// A path outside the bundle has no canonical form inside it, and the worker
// drops it — which would read as a file that was added and never written.
it('refuses a path that escapes the bundle', () => {
expect(dbtModulePath('../secrets.sql', {})).toEqual({ error: expect.stringContaining('..') })
expect(dbtModulePath('/etc/x.sql', {})).toEqual({ error: expect.stringContaining('relative') })
})
it('refuses an extension dbt does not read', () => {
expect(dbtModulePath('models/x.txt', {})).toEqual({
error: expect.stringContaining('must end with')
})
})
})
// Every write path canonicalises, so a read that compares the constant exactly
// would neither find a project imported under a redundant spelling nor protect
// it from deletion.
it('resolves the key a bundle actually holds the project file under', () => {
expect(dbtProjectFileKey({ './dbt_project.yml': mod(PROJECT) })).toBe('./dbt_project.yml')
expect(dbtProjectFileKey({})).toBeUndefined()
})
describe('dbtModelSelector', () => {
// Package-qualified, because a bare leaf name also matches a dependency
// package's model of the same name.
it('selects a model under the projects own model-paths', () => {
const bundle = { 'dbt_project.yml': mod(PROJECT), 'models/orders.sql': mod('select 1') }
expect(dbtModelSelector(bundle, 'models/orders.sql')).toBe('orders,package:jaffle')
})
// A project may put its models anywhere; a macro or singular test is `.sql`
// too and is not selectable by name, so those fall back to the whole project.
it('honours a custom model-paths and skips what is not a model', () => {
const bundle = {
'dbt_project.yml': mod('name: jaffle\nmodel-paths: ["transform"]\n'),
'transform/orders.sql': mod('select 1'),
'macros/cents.sql': mod('{% macro cents() %}{% endmacro %}')
}
expect(dbtModelSelector(bundle, 'transform/orders.sql')).toBe('orders,package:jaffle')
expect(dbtModelSelector(bundle, 'macros/cents.sql')).toBeUndefined()
})
it('finds the project file under a redundant spelling', () => {
const bundle = { './dbt_project.yml': mod(PROJECT), 'models/orders.sql': mod('select 1') }
expect(dbtModelSelector(bundle, 'models/orders.sql')).toBe('orders,package:jaffle')
})
})