|
|
@@ -0,0 +1,193 @@
|
|
|
+// Licensed to Cloudera, Inc. under one
|
|
|
+// or more contributor license agreements. See the NOTICE file
|
|
|
+// distributed with this work for additional information
|
|
|
+// regarding copyright ownership. Cloudera, Inc. licenses this file
|
|
|
+// to you under the Apache License, Version 2.0 (the
|
|
|
+// "License"); you may not use this file except in compliance
|
|
|
+// with the License. You may obtain a copy of the License at
|
|
|
+//
|
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+//
|
|
|
+// Unless required by applicable law or agreed to in writing, software
|
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+// See the License for the specific language governing permissions and
|
|
|
+// limitations under the License.
|
|
|
+
|
|
|
+import huePubSub from './huePubSub';
|
|
|
+
|
|
|
+describe('huePubSub', () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ const topics = huePubSub.getTopics();
|
|
|
+ Object.keys(topics).forEach(key => {
|
|
|
+ huePubSub.removeAll(key);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('subscribe and publish', () => {
|
|
|
+ it('should call listener when topic is published', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener);
|
|
|
+ huePubSub.publish('test-topic', { data: 'test' });
|
|
|
+ expect(listener).toHaveBeenCalledWith({ data: 'test' });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should call multiple listeners for the same topic', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener1);
|
|
|
+ huePubSub.subscribe('test-topic', listener2);
|
|
|
+ huePubSub.publish('test-topic', 'test data');
|
|
|
+ expect(listener1).toHaveBeenCalledWith('test data');
|
|
|
+ expect(listener2).toHaveBeenCalledWith('test data');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should not call listener if topic does not exist', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener);
|
|
|
+ huePubSub.publish('other-topic', 'test');
|
|
|
+ expect(listener).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('remove subscription', () => {
|
|
|
+ it('should not call listener after subscription is removed', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ const subscription = huePubSub.subscribe('test-topic', listener);
|
|
|
+ subscription.remove();
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should handle multiple subscriptions removal correctly (bug fix test)', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ const listener3 = jest.fn();
|
|
|
+
|
|
|
+ huePubSub.subscribe('test-topic', listener1);
|
|
|
+ const sub2 = huePubSub.subscribe('test-topic', listener2);
|
|
|
+ huePubSub.subscribe('test-topic', listener3);
|
|
|
+
|
|
|
+ // Remove the middle subscription
|
|
|
+ sub2.remove();
|
|
|
+
|
|
|
+ // Publish and verify only listener1 and listener3 are called
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener1).toHaveBeenCalledWith('test');
|
|
|
+ expect(listener2).not.toHaveBeenCalled();
|
|
|
+ expect(listener3).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should handle removal of first subscription correctly', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ const listener3 = jest.fn();
|
|
|
+
|
|
|
+ const sub1 = huePubSub.subscribe('test-topic', listener1);
|
|
|
+ huePubSub.subscribe('test-topic', listener2);
|
|
|
+ huePubSub.subscribe('test-topic', listener3);
|
|
|
+
|
|
|
+ sub1.remove();
|
|
|
+
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener1).not.toHaveBeenCalled();
|
|
|
+ expect(listener2).toHaveBeenCalledWith('test');
|
|
|
+ expect(listener3).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should handle removing same subscription multiple times', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ const subscription = huePubSub.subscribe('test-topic', listener);
|
|
|
+ subscription.remove();
|
|
|
+ subscription.remove(); // Should not throw error
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('subscribeOnce', () => {
|
|
|
+ it('should call listener only once', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribeOnce('test-topic', listener, 'test-app');
|
|
|
+ huePubSub.publish('test-topic', 'first');
|
|
|
+ huePubSub.publish('test-topic', 'second');
|
|
|
+ expect(listener).toHaveBeenCalledTimes(1);
|
|
|
+ expect(listener).toHaveBeenCalledWith('first');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should auto-remove subscription after first call', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribeOnce('test-topic', listener, 'test-app');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ const topics = huePubSub.getTopics();
|
|
|
+ expect(topics['test-topic'].length).toBe(0);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('removeAll', () => {
|
|
|
+ it('should remove all subscriptions for a topic', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener1);
|
|
|
+ huePubSub.subscribe('test-topic', listener2);
|
|
|
+ huePubSub.removeAll('test-topic');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener1).not.toHaveBeenCalled();
|
|
|
+ expect(listener2).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('pauseAppSubscribers and resumeAppSubscribers', () => {
|
|
|
+ it('should pause app subscribers', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener, 'test-app');
|
|
|
+ huePubSub.pauseAppSubscribers('test-app');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should resume app subscribers', () => {
|
|
|
+ const listener = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener, 'test-app');
|
|
|
+ huePubSub.pauseAppSubscribers('test-app');
|
|
|
+ huePubSub.resumeAppSubscribers('test-app');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should only affect specific app subscribers', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener1, 'app1');
|
|
|
+ huePubSub.subscribe('test-topic', listener2, 'app2');
|
|
|
+ huePubSub.pauseAppSubscribers('app1');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener1).not.toHaveBeenCalled();
|
|
|
+ expect(listener2).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('clearAppSubscribers', () => {
|
|
|
+ it('should clear all subscribers for an app', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ huePubSub.subscribe('test-topic', listener1, 'test-app');
|
|
|
+ huePubSub.subscribe('test-topic', listener2, 'other-app');
|
|
|
+ huePubSub.clearAppSubscribers('test-app');
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener1).not.toHaveBeenCalled();
|
|
|
+ expect(listener2).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should work correctly with remove() after clearAppSubscribers', () => {
|
|
|
+ const listener1 = jest.fn();
|
|
|
+ const listener2 = jest.fn();
|
|
|
+ const sub1 = huePubSub.subscribe('test-topic', listener1, 'test-app');
|
|
|
+ huePubSub.subscribe('test-topic', listener2, 'other-app');
|
|
|
+ huePubSub.clearAppSubscribers('test-app');
|
|
|
+ sub1.remove(); // Should not throw error
|
|
|
+ huePubSub.publish('test-topic', 'test');
|
|
|
+ expect(listener2).toHaveBeenCalledWith('test');
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|