| 1 | package eventwire |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "strings" |
| 6 | "testing" |
| 7 | |
| 8 | "reasonix/internal/event" |
| 9 | ) |
| 10 | |
| 11 | // TestToWireExtensionSurfacePayloads covers the stage-8a extension surface |
| 12 | // events: status rides ExtensionStatus, card/form/notification ride |
| 13 | // ExtensionSurface, and each carries exactly its own sub-struct. |
| 14 | func TestToWireExtensionSurfacePayloads(t *testing.T) { |
| 15 | progress := 0.5 |
| 16 | tests := []struct { |
| 17 | name string |
| 18 | in event.Event |
| 19 | want []string |
| 20 | }{ |
| 21 | { |
| 22 | name: "status", |
| 23 | in: event.Event{Kind: event.ExtensionStatus, Extension: &event.ExtensionSurfacePayload{ |
| 24 | PluginID: "alpha", SurfaceID: "s1", SessionID: "sess", Generation: 7, |
| 25 | Kind: event.ExtensionSurfaceStatus, |
| 26 | Status: &event.ExtensionStatusView{Label: "working", Detail: "half", Severity: "warn", Progress: &progress}, |
| 27 | }}, |
| 28 | want: []string{ |
| 29 | `"kind":"extension_status"`, `"extension":{"pluginId":"alpha","surfaceId":"s1","sessionId":"sess","generation":7,"kind":"status"`, |
| 30 | `"status":{"label":"working","detail":"half","severity":"warn","progress":0.5}`, |
| 31 | }, |
| 32 | }, |
| 33 | { |
| 34 | name: "card", |
| 35 | in: event.Event{Kind: event.ExtensionSurface, Extension: &event.ExtensionSurfacePayload{ |
| 36 | PluginID: "alpha", SurfaceID: "c1", Kind: event.ExtensionSurfaceCard, |
| 37 | Card: &event.ExtensionCardView{ |
| 38 | Title: "T", Markdown: "**m**", Text: "x", Progress: &progress, |
| 39 | Fields: []event.ExtensionKeyValue{{Key: "k", Value: "v"}}, |
| 40 | Actions: []event.ExtensionActionRef{{ActionID: "act1", Label: "go"}}, |
| 41 | }, |
| 42 | }}, |
| 43 | want: []string{ |
| 44 | `"kind":"extension_surface"`, `"kind":"card"`, |
| 45 | `"card":{"title":"T","markdown":"**m**","text":"x","fields":[{"key":"k","value":"v"}],"progress":0.5,"actions":[{"actionId":"act1","label":"go"}]}`, |
| 46 | }, |
| 47 | }, |
| 48 | { |
| 49 | name: "form", |
| 50 | in: event.Event{Kind: event.ExtensionSurface, Extension: &event.ExtensionSurfacePayload{ |
| 51 | PluginID: "alpha", SurfaceID: "f1", Kind: event.ExtensionSurfaceForm, |
| 52 | Form: &event.ExtensionFormView{ |
| 53 | Title: "f", Message: "m", |
| 54 | Fields: []event.ExtensionFormField{{ |
| 55 | Key: "field1", Label: "L", Kind: "multiselect", |
| 56 | Options: []string{"a", "b"}, Default: "a", Required: true, |
| 57 | }}, |
| 58 | }, |
| 59 | }}, |
| 60 | want: []string{ |
| 61 | `"kind":"extension_surface"`, `"kind":"form"`, |
| 62 | `"form":{"title":"f","message":"m","fields":[{"key":"field1","label":"L","kind":"multiselect","options":["a","b"],"default":"a","required":true}]}`, |
| 63 | }, |
| 64 | }, |
| 65 | { |
| 66 | name: "notification", |
| 67 | in: event.Event{Kind: event.ExtensionSurface, Extension: &event.ExtensionSurfacePayload{ |
| 68 | PluginID: "alpha", SurfaceID: "n1", Kind: event.ExtensionSurfaceNotification, |
| 69 | Notification: &event.ExtensionNotificationView{Title: "n", Body: "b", Severity: "error"}, |
| 70 | }}, |
| 71 | want: []string{ |
| 72 | `"kind":"extension_surface"`, `"kind":"notification"`, |
| 73 | `"notification":{"title":"n","body":"b","severity":"error"}`, |
| 74 | }, |
| 75 | }, |
| 76 | } |
| 77 | for _, tt := range tests { |
| 78 | t.Run(tt.name, func(t *testing.T) { |
| 79 | b, err := json.Marshal(ToWire(tt.in)) |
| 80 | if err != nil { |
| 81 | t.Fatalf("marshal: %v", err) |
| 82 | } |
| 83 | s := string(b) |
| 84 | for _, want := range tt.want { |
| 85 | if !strings.Contains(s, want) { |
| 86 | t.Fatalf("%s JSON = %s, want it to contain %s", tt.name, s, want) |
| 87 | } |
| 88 | } |
| 89 | }) |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | // TestToWireExtensionNilPayload marshals no extension object instead of a |
| 94 | // half-filled one when the payload is missing. |
| 95 | func TestToWireExtensionNilPayload(t *testing.T) { |
| 96 | b, err := json.Marshal(ToWire(event.Event{Kind: event.ExtensionStatus})) |
| 97 | if err != nil { |
| 98 | t.Fatalf("marshal: %v", err) |
| 99 | } |
| 100 | if strings.Contains(string(b), `"extension"`) { |
| 101 | t.Fatalf("nil payload JSON = %s, must omit the extension field", b) |
| 102 | } |
| 103 | } |
| 104 |