3c7400ca2a
The TS update-routing used the deprecated `!!stack.GitConfig` to flag a git-backed stack, which can diverge from the canonical Go daemon routing (`IsGit: st.WorkflowID != 0`) on the new Workflow/Source model. Derive it from WorkflowID instead (added WorkflowID to the client Stack type). The stack-type filter (Type === DockerCompose) was already in place and tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
import { Stack, StackType } from '@/react/common/stacks/types';
|
|
import { COMPOSE_STACK_NAME_LABEL } from '@/react/constants';
|
|
|
|
import { resolveContainerUpdatePath } from './resolveContainerUpdatePath';
|
|
|
|
function buildStack(overrides: Partial<Stack>): Stack {
|
|
return {
|
|
Id: 1,
|
|
Name: 'my-stack',
|
|
EndpointId: 3,
|
|
Type: StackType.DockerCompose,
|
|
...overrides,
|
|
} as Stack;
|
|
}
|
|
|
|
describe('resolveContainerUpdatePath', () => {
|
|
it('returns standalone when there is no compose project label', () => {
|
|
expect(
|
|
resolveContainerUpdatePath({ labels: {}, environmentId: 3 }, [])
|
|
).toEqual({ kind: 'standalone' });
|
|
});
|
|
|
|
it('returns stack when the compose project matches a Portainer stack', () => {
|
|
const stack = buildStack({ Id: 7, Name: 'my-stack', EndpointId: 3 });
|
|
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'my-stack' },
|
|
environmentId: 3,
|
|
},
|
|
[stack]
|
|
)
|
|
).toEqual({ kind: 'stack', stackId: 7, isGitStack: false });
|
|
});
|
|
|
|
it('flags git stacks (non-zero WorkflowID) so they redeploy via the git path', () => {
|
|
const stack = buildStack({
|
|
Id: 9,
|
|
Name: 'git-stack',
|
|
EndpointId: 3,
|
|
WorkflowID: 42,
|
|
});
|
|
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'git-stack' },
|
|
environmentId: 3,
|
|
},
|
|
[stack]
|
|
)
|
|
).toEqual({ kind: 'stack', stackId: 9, isGitStack: true });
|
|
});
|
|
|
|
it('does not flag a git stack from a deprecated GitConfig alone (no WorkflowID)', () => {
|
|
// GitConfig is deprecated and can diverge from the Workflow/Source model;
|
|
// only a non-zero WorkflowID marks a stack git-backed (mirrors the Go daemon).
|
|
const stack = buildStack({
|
|
Id: 11,
|
|
Name: 'git-stack',
|
|
EndpointId: 3,
|
|
GitConfig: { URL: 'https://example.com/repo.git' } as Stack['GitConfig'],
|
|
});
|
|
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'git-stack' },
|
|
environmentId: 3,
|
|
},
|
|
[stack]
|
|
)
|
|
).toEqual({ kind: 'stack', stackId: 11, isGitStack: false });
|
|
});
|
|
|
|
it('returns external when the compose project has no matching stack', () => {
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'unknown-project' },
|
|
environmentId: 3,
|
|
},
|
|
[buildStack({ Name: 'other' })]
|
|
)
|
|
).toEqual({ kind: 'external' });
|
|
});
|
|
|
|
it('returns external when a same-named stack is not a compose stack', () => {
|
|
const stack = buildStack({
|
|
Name: 'my-stack',
|
|
EndpointId: 3,
|
|
Type: StackType.Kubernetes,
|
|
});
|
|
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'my-stack' },
|
|
environmentId: 3,
|
|
},
|
|
[stack]
|
|
)
|
|
).toEqual({ kind: 'external' });
|
|
});
|
|
|
|
it('does not match a stack from a different endpoint', () => {
|
|
const stack = buildStack({ Name: 'my-stack', EndpointId: 99 });
|
|
|
|
expect(
|
|
resolveContainerUpdatePath(
|
|
{
|
|
labels: { [COMPOSE_STACK_NAME_LABEL]: 'my-stack' },
|
|
environmentId: 3,
|
|
},
|
|
[stack]
|
|
)
|
|
).toEqual({ kind: 'external' });
|
|
});
|
|
});
|