Skip to content
6 changes: 3 additions & 3 deletions src/commands/apps/channel-rules/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default class ChannelRulesCreateCommand extends ControlBaseCommand {
authenticated: flags.authenticated,
batchingEnabled: flags["batching-enabled"],
batchingInterval: flags["batching-interval"],
channelNamespace: flags.name,
id: flags.name,
conflationEnabled: flags["conflation-enabled"],
conflationInterval: flags["conflation-interval"],
conflationKey: flags["conflation-key"],
Expand Down Expand Up @@ -209,7 +209,7 @@ export default class ChannelRulesCreateCommand extends ControlBaseCommand {
);
}

if (createdNamespace.batchingInterval !== undefined) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should these be falsy checks?

        if (!createdNamespace.batchingInterval) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using !createdNamespace.batchingInterval would be problematic because batchingInterval could legitimately be 0 (a valid number), and !0 evaluates to true, which would incorrectly skip displaying a valid interval of 0. The typeof === "number" check is the safest approach because:

  1. It handles null (from API) → typeof null === "object" → skipped ✓
  2. It handles undefined (absent) → typeof undefined === "undefined" → skipped ✓
  3. It handles 0 (valid interval) → typeof 0 === "number" → displayed ✓
  4. It satisfies ESLint's eqeqeq rule (no loose equality)

if (createdNamespace.batchingInterval != null) {
this.log(
`Batching Interval: ${chalk.green(createdNamespace.batchingInterval.toString())}`,
);
Expand All @@ -221,7 +221,7 @@ export default class ChannelRulesCreateCommand extends ControlBaseCommand {
);
}

if (createdNamespace.conflationInterval !== undefined) {
if (createdNamespace.conflationInterval != null) {
this.log(
`Conflation Interval: ${chalk.green(createdNamespace.conflationInterval.toString())}`,
);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/apps/channel-rules/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default class ChannelRulesDeleteCommand extends ControlBaseCommand {
);
}

if (namespace.batchingInterval !== undefined) {
if (namespace.batchingInterval != null) {
this.log(
`Batching Interval: ${chalk.green(namespace.batchingInterval.toString())}`,
);
Expand All @@ -147,7 +147,7 @@ export default class ChannelRulesDeleteCommand extends ControlBaseCommand {
);
}

if (namespace.conflationInterval !== undefined) {
if (namespace.conflationInterval != null) {
this.log(
`Conflation Interval: ${chalk.green(namespace.conflationInterval.toString())}`,
);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/apps/channel-rules/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export default class ChannelRulesUpdateCommand extends ControlBaseCommand {
);
}

if (updatedNamespace.batchingInterval !== undefined) {
if (updatedNamespace.batchingInterval != null) {
this.log(
`Batching Interval: ${chalk.green(updatedNamespace.batchingInterval.toString())}`,
);
Expand All @@ -317,7 +317,7 @@ export default class ChannelRulesUpdateCommand extends ControlBaseCommand {
);
}

if (updatedNamespace.conflationInterval !== undefined) {
if (updatedNamespace.conflationInterval != null) {
this.log(
`Conflation Interval: ${chalk.green(updatedNamespace.conflationInterval.toString())}`,
);
Expand Down
2 changes: 1 addition & 1 deletion src/services/control-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export class ControlApi {
authenticated?: boolean;
batchingEnabled?: boolean;
batchingInterval?: number;
channelNamespace: string;
id: string;
conflationEnabled?: boolean;
conflationInterval?: number;
conflationKey?: string;
Comment thread
sacOO7 marked this conversation as resolved.
Expand Down
64 changes: 32 additions & 32 deletions test/integration/control-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Control API Integration Tests', () => {
this.skip();
return;
}

controlApi = new ControlApi({
accessToken,
logErrors: false
Expand Down Expand Up @@ -120,31 +120,31 @@ describe('Control API Integration Tests', () => {
};

const app = await controlApi.createApp(appData);

expect(app).to.have.property('id');
expect(app).to.have.property('name', appData.name);
expect(app).to.have.property('tlsOnly', false);
expect(app).to.have.property('accountId', testAccountId);

// Track for cleanup
createdResources.apps.push(app.id);
testAppId = app.id;
});

it('should list apps', async () => {
const apps = await controlApi.listApps();

expect(apps).to.be.an('array');
expect(apps.length).to.be.greaterThan(0);

// Should include our test app
const testApp = apps.find(app => app.id === testAppId);
expect(testApp).to.exist;
});

it('should get a specific app', async () => {
const app = await controlApi.getApp(testAppId);

expect(app).to.have.property('id', testAppId);
expect(app).to.have.property('accountId', testAccountId);
});
Expand All @@ -156,7 +156,7 @@ describe('Control API Integration Tests', () => {
};

const updatedApp = await controlApi.updateApp(testAppId, updateData);

expect(updatedApp).to.have.property('id', testAppId);
expect(updatedApp).to.have.property('name', updateData.name);
expect(updatedApp).to.have.property('tlsOnly', true);
Expand All @@ -175,30 +175,30 @@ describe('Control API Integration Tests', () => {
};

const key = await controlApi.createKey(testAppId, keyData);

expect(key).to.have.property('id');
expect(key).to.have.property('name', keyData.name);
expect(key).to.have.property('appId', testAppId);
expect(key).to.have.property('key');

testKeyId = key.id;
createdResources.keys.push(key.id);
});

it('should list API keys', async () => {
const keys = await controlApi.listKeys(testAppId);

expect(keys).to.be.an('array');
expect(keys.length).to.be.greaterThan(0);

// Should include our test key
const testKey = keys.find(key => key.id === testKeyId);
expect(testKey).to.exist;
});

it('should get a specific API key', async () => {
const key = await controlApi.getKey(testAppId, testKeyId);

expect(key).to.have.property('id', testKeyId);
expect(key).to.have.property('appId', testAppId);
});
Expand All @@ -213,7 +213,7 @@ describe('Control API Integration Tests', () => {
};

const updatedKey = await controlApi.updateKey(testAppId, testKeyId, updateData);

expect(updatedKey).to.have.property('id', testKeyId);
expect(updatedKey).to.have.property('name', updateData.name);
});
Expand All @@ -232,23 +232,23 @@ describe('Control API Integration Tests', () => {
};

const queue = await controlApi.createQueue(testAppId, queueData);

expect(queue).to.have.property('id');
expect(queue).to.have.property('name', testQueueName);
expect(queue).to.have.property('appId', testAppId);
expect(queue).to.have.property('maxLength', 1000);
expect(queue).to.have.property('ttl', 3600);
expect(queue).to.have.property('region', 'us-east-1-a');

createdResources.queues.push(testQueueName);
});

it('should list queues', async () => {
const queues = await controlApi.listQueues(testAppId);

expect(queues).to.be.an('array');
expect(queues.length).to.be.greaterThan(0);

// Should include our test queue
const testQueue = queues.find(queue => queue.name === testQueueName);
expect(testQueue).to.exist;
Expand Down Expand Up @@ -279,32 +279,32 @@ describe('Control API Integration Tests', () => {
};

const rule = await controlApi.createRule(testAppId, ruleData);

expect(rule).to.have.property('id');
expect(rule).to.have.property('appId', testAppId);
expect(rule).to.have.property('ruleType', 'http');
expect(rule).to.have.property('requestMode', 'single');
expect(rule).to.have.property('source');
expect(rule.source).to.have.property('channelFilter', 'test-channel');

testRuleId = rule.id;
createdResources.rules.push(rule.id);
});

it('should list integration rules', async () => {
const rules = await controlApi.listRules(testAppId);

expect(rules).to.be.an('array');
expect(rules.length).to.be.greaterThan(0);

// Should include our test rule
const testRule = rules.find(rule => rule.id === testRuleId);
expect(testRule).to.exist;
});

it('should get a specific integration rule', async () => {
const rule = await controlApi.getRule(testAppId, testRuleId);

expect(rule).to.have.property('id', testRuleId);
expect(rule).to.have.property('appId', testAppId);
});
Expand All @@ -321,7 +321,7 @@ describe('Control API Integration Tests', () => {
};

const updatedRule = await controlApi.updateRule(testAppId, testRuleId, updateData);

expect(updatedRule).to.have.property('id', testRuleId);
expect(updatedRule.source).to.have.property('channelFilter', 'updated-channel');
});
Expand All @@ -332,38 +332,38 @@ describe('Control API Integration Tests', () => {

it('should create a new namespace', async () => {
const namespaceData = {
channelNamespace: `test-namespace-${Date.now()}`,
id: `test-namespace-${Date.now()}`,
persisted: true,
pushEnabled: false,
tlsOnly: true
};

const namespace = await controlApi.createNamespace(testAppId, namespaceData);

expect(namespace).to.have.property('id');
expect(namespace).to.have.property('appId', testAppId);
expect(namespace).to.have.property('persisted', true);
expect(namespace).to.have.property('pushEnabled', false);
expect(namespace).to.have.property('tlsOnly', true);

testNamespaceId = namespace.id;
createdResources.namespaces.push(namespace.id);
});

it('should list namespaces', async () => {
const namespaces = await controlApi.listNamespaces(testAppId);

expect(namespaces).to.be.an('array');
expect(namespaces.length).to.be.greaterThan(0);

// Should include our test namespace
const testNamespace = namespaces.find(ns => ns.id === testNamespaceId);
expect(testNamespace).to.exist;
});

it('should get a specific namespace', async () => {
const namespace = await controlApi.getNamespace(testAppId, testNamespaceId);

expect(namespace).to.have.property('id', testNamespaceId);
expect(namespace).to.have.property('appId', testAppId);
});
Expand All @@ -377,7 +377,7 @@ describe('Control API Integration Tests', () => {
};

const updatedNamespace = await controlApi.updateNamespace(testAppId, testNamespaceId, updateData);

expect(updatedNamespace).to.have.property('id', testNamespaceId);
expect(updatedNamespace).to.have.property('persisted', false);
expect(updatedNamespace).to.have.property('pushEnabled', true);
Expand Down Expand Up @@ -434,7 +434,7 @@ describe('Control API Integration Tests', () => {
}

const results = await Promise.all(promises);

expect(results).to.have.length(5);
results.forEach(apps => {
expect(apps).to.be.an('array');
Expand All @@ -452,4 +452,4 @@ describe('Control API Integration Tests', () => {
}
});
});
});
});
Loading