|
9 | 9 |
|
10 | 10 | "github.com/charmbracelet/bubbles/spinner" |
11 | 11 | tea "github.com/charmbracelet/bubbletea" |
| 12 | + "github.com/charmbracelet/lipgloss" |
12 | 13 |
|
13 | 14 | "unic/internal/config" |
14 | 15 | "unic/internal/domain" |
@@ -472,6 +473,123 @@ func TestEC2BrowserDetailViewShowsMetadata(t *testing.T) { |
472 | 473 | } |
473 | 474 | } |
474 | 475 |
|
| 476 | +func TestEC2BrowserDetailViewKeepsRowsSeparateAndClipped(t *testing.T) { |
| 477 | + m := New(testConfig(), "", "dev") |
| 478 | + m.screen = screenEC2InstanceBrowserDetail |
| 479 | + m.width = 96 |
| 480 | + m.height = 30 |
| 481 | + m.ec2Browser.selected = &awsservice.EC2Instance{ |
| 482 | + InstanceID: "i-0f237d69dbc37d27f", |
| 483 | + Name: "plantadmext-plted_apnortheast2-v075", |
| 484 | + State: "running", |
| 485 | + InstanceType: "t4g.medium", |
| 486 | + SecurityGroups: []awsservice.EC2InstanceSecurityGroup{ |
| 487 | + {GroupID: "sg-054e6a98f4a972b67", Name: "plantadmext-plted_apnortheast2"}, |
| 488 | + {GroupID: "sg-0844134f83a41ab59", Name: "vpc-00a9c49eb2111f495-querypie-joined-sg-260205124724"}, |
| 489 | + }, |
| 490 | + Tags: map[string]string{ |
| 491 | + "ansible-tags": "all app plantadmext apps_version plantadmext-release-202604221456-2f31d19c.jar", |
| 492 | + "aws:autoscaling:groupName": "coreprobeworker-plted_apnortheast2-v020", |
| 493 | + "aws:ec2launchtemplate:id": "lt-09f7820d193aba7d1", |
| 494 | + "branch": "main service_jar_file=plantadmext/main/plantadmext-release-202604221456-2f31d19c.jar", |
| 495 | + }, |
| 496 | + } |
| 497 | + |
| 498 | + view := stripANSI(m.View()) |
| 499 | + lines := strings.Split(view, "\n") |
| 500 | + for _, line := range lines { |
| 501 | + if width := lipgloss.Width(line); width > m.width { |
| 502 | + t.Fatalf("expected EC2 detail line to fit width %d, got %d: %q", m.width, width, line) |
| 503 | + } |
| 504 | + } |
| 505 | + for _, want := range []string{"Instance ID", "Security Groups", "Tags", "ansible-tags", "branch"} { |
| 506 | + found := false |
| 507 | + for _, line := range lines { |
| 508 | + if strings.Contains(line, want) { |
| 509 | + found = true |
| 510 | + break |
| 511 | + } |
| 512 | + } |
| 513 | + if !found { |
| 514 | + t.Fatalf("expected EC2 detail view to contain separate row %q, got %q", want, view) |
| 515 | + } |
| 516 | + } |
| 517 | + for _, line := range lines { |
| 518 | + if strings.Contains(line, "oupName") && !strings.Contains(line, "aws:autoscaling:groupName") { |
| 519 | + t.Fatalf("expected long tag key to stay on one row without wrapping, got fragment row %q", line) |
| 520 | + } |
| 521 | + } |
| 522 | +} |
| 523 | + |
| 524 | +func TestEC2BrowserRelatedListNavigationAndFilter(t *testing.T) { |
| 525 | + m := New(testConfig(), "", "dev") |
| 526 | + m.screen = screenEC2InstanceBrowserRelatedList |
| 527 | + m.ec2Browser.selected = &awsservice.EC2Instance{InstanceID: "i-123", Name: "prod-web"} |
| 528 | + m.ec2Browser.relatedKind = ec2RelatedTargetGroups |
| 529 | + m.ec2Browser.relatedItems = []ec2RelatedItem{ |
| 530 | + { |
| 531 | + title: "prod-tg HTTP:80 [healthy]", |
| 532 | + filter: "prod-tg http healthy", |
| 533 | + details: []detailRow{ |
| 534 | + {"Name", "prod-tg"}, |
| 535 | + }, |
| 536 | + }, |
| 537 | + { |
| 538 | + title: "dev-tg HTTP:8080 [unused]", |
| 539 | + filter: "dev-tg http unused", |
| 540 | + details: []detailRow{ |
| 541 | + {"Name", "dev-tg"}, |
| 542 | + }, |
| 543 | + }, |
| 544 | + } |
| 545 | + m.ec2Browser.filteredRelated = m.ec2Browser.relatedItems |
| 546 | + |
| 547 | + updated, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'k'}}) |
| 548 | + model := updated.(Model) |
| 549 | + if model.ec2Browser.relatedIdx != 1 { |
| 550 | + t.Fatalf("expected related list up from first to wrap to last, got %d", model.ec2Browser.relatedIdx) |
| 551 | + } |
| 552 | + |
| 553 | + updated, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'/'}}) |
| 554 | + model = updated.(Model) |
| 555 | + for _, ch := range []rune("prod") { |
| 556 | + updated, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{ch}}) |
| 557 | + model = updated.(Model) |
| 558 | + } |
| 559 | + if len(model.ec2Browser.filteredRelated) != 1 { |
| 560 | + t.Fatalf("expected 1 filtered related item, got %d", len(model.ec2Browser.filteredRelated)) |
| 561 | + } |
| 562 | + if model.ec2Browser.filteredRelated[0].title != "prod-tg HTTP:80 [healthy]" { |
| 563 | + t.Fatalf("unexpected filtered related item: %+v", model.ec2Browser.filteredRelated[0]) |
| 564 | + } |
| 565 | +} |
| 566 | + |
| 567 | +func TestEC2RelationshipsLoadedOpensRequestedRelatedList(t *testing.T) { |
| 568 | + m := New(testConfig(), "", "dev") |
| 569 | + m.screen = screenLoading |
| 570 | + msg := ec2RelationshipsLoadedMsg{ |
| 571 | + kind: ec2RelatedLoadBalancers, |
| 572 | + relationships: &awsservice.EC2InstanceRelationships{ |
| 573 | + InstanceID: "i-123", |
| 574 | + LoadBalancers: []awsservice.EC2LoadBalancer{ |
| 575 | + {Name: "app-lb", DNSName: "app.example.com", Type: "application", State: "active"}, |
| 576 | + }, |
| 577 | + }, |
| 578 | + } |
| 579 | + |
| 580 | + updated, _ := m.Update(msg) |
| 581 | + model := updated.(Model) |
| 582 | + if model.screen != screenEC2InstanceBrowserRelatedList { |
| 583 | + t.Fatalf("expected related list screen, got %d", model.screen) |
| 584 | + } |
| 585 | + if model.ec2Browser.relatedKind != ec2RelatedLoadBalancers { |
| 586 | + t.Fatalf("expected load balancer related kind, got %q", model.ec2Browser.relatedKind) |
| 587 | + } |
| 588 | + if len(model.ec2Browser.relatedItems) != 1 || !strings.Contains(model.ec2Browser.relatedItems[0].title, "app-lb") { |
| 589 | + t.Fatalf("unexpected related items: %+v", model.ec2Browser.relatedItems) |
| 590 | + } |
| 591 | +} |
| 592 | + |
475 | 593 | func TestReachabilityFeatureOpensRegionSelection(t *testing.T) { |
476 | 594 | m := New(testConfig(), "", "dev") |
477 | 595 | m.screen = screenFeatureList |
|
0 commit comments