Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/commands/channels/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default class ChannelsPublish extends AblyBaseCommand {
'$ ably channels publish --transport realtime my-channel "Using realtime transport"',
'$ ably channels publish my-channel "Hello World" --json',
'$ ably channels publish my-channel "Hello World" --pretty-json',
'$ ably channels publish my-channel \'{"data":"Push notification","extras":{"push":{"notification":{"title":"Hello","body":"World"}}}}\'',
];

static override flags = {
Expand Down Expand Up @@ -206,11 +207,22 @@ export default class ChannelsPublish extends AblyBaseCommand {
delete messageData.name;
}

// Add extras if provided in the message data (before processing data)
if (
messageData.extras &&
typeof messageData.extras === "object" &&
Object.keys(messageData.extras).length > 0
) {
message.extras = messageData.extras;
// Remove extras from messageData to avoid duplication in data
delete messageData.extras;
}

// If data is explicitly provided in the message, use it
if ("data" in messageData) {
message.data = messageData.data;
} else {
// Otherwise use the entire messageData as the data
} else if (Object.keys(messageData).length > 0) {
// Otherwise use the entire messageData object (not empty) as the data
message.data = messageData;
}

Expand Down
78 changes: 78 additions & 0 deletions test/unit/commands/channels/publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,82 @@ describe("ChannelsPublish", function () {
expect(stdout).toMatch(/error/i);
});
});

describe("should publish a message with data and extras", function () {
it("should include extras.push when provided in message data", async function () {
const restMock = getMockAblyRest();
const channel = restMock.channels._getChannel("test-channel");

await runCommand(
[
"channels:publish",
"test-channel",
'{"data":"hello","extras":{"push":{"notification":{"title":"Test","body":"Push notification"}}}}',
"--transport",
"rest",
],
import.meta.url,
);

expect(channel.publish).toHaveBeenCalledOnce();
const publishArgs = channel.publish.mock.calls[0][0];
expect(publishArgs).toHaveProperty("data", "hello");
expect(publishArgs).toHaveProperty("extras");
expect(publishArgs.extras).toHaveProperty("push");
expect(publishArgs.extras.push).toEqual({
notification: { title: "Test", body: "Push notification" },
});
});

it("should publish a message when only extras is provided without data", async function () {
const restMock = getMockAblyRest();
const channel = restMock.channels._getChannel("test-channel");

await runCommand(
[
"channels:publish",
"test-channel",
'{"extras":{"push":{"notification":{"title":"Extras only","body":"No data field"}}}}',
"--transport",
"rest",
],
import.meta.url,
);

expect(channel.publish).toHaveBeenCalledOnce();
const publishArgs = channel.publish.mock.calls[0][0];
expect(publishArgs).toHaveProperty("extras");
expect(publishArgs.extras).toHaveProperty("push");
expect(publishArgs.extras.push).toEqual({
notification: { title: "Extras only", body: "No data field" },
});
expect(publishArgs).not.toHaveProperty("data");
});

it("should preserve name when extras is provided without data", async function () {
const restMock = getMockAblyRest();
const channel = restMock.channels._getChannel("test-channel");

await runCommand(
[
"channels:publish",
"test-channel",
'{"name":"eventName","extras":{"push":{"notification":{"title":"With name","body":"No data field"}}}}',
"--transport",
"rest",
],
import.meta.url,
);

expect(channel.publish).toHaveBeenCalledOnce();
const publishArgs = channel.publish.mock.calls[0][0];
expect(publishArgs).toHaveProperty("name", "eventName");
expect(publishArgs).toHaveProperty("extras");
expect(publishArgs.extras).toHaveProperty("push");
expect(publishArgs.extras.push).toEqual({
notification: { title: "With name", body: "No data field" },
});
expect(publishArgs).not.toHaveProperty("data");
});
});
});
Loading