package com.devicehive.handler.notification; /* * #%L * DeviceHive Backend Logic * %% * Copyright (C) 2016 DataArt * %% * Licensed 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. * #L% */ import com.devicehive.eventbus.EventBus; import com.devicehive.model.DeviceNotification; import com.devicehive.model.eventbus.Subscriber; import com.devicehive.model.eventbus.Subscription; import com.devicehive.model.rpc.Action; import com.devicehive.model.rpc.NotificationSubscribeRequest; import com.devicehive.service.HazelcastService; import com.devicehive.shim.api.Request; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.UUID.randomUUID; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class NotificationSubscribeRequestHandlerUnitTest { private EventBus eventBus; private HazelcastService hazelcastService; private NotificationSubscribeRequestHandler handler; @Rule public ExpectedException ex = ExpectedException.none(); @Before public void setUp() throws Exception { this.handler = new NotificationSubscribeRequestHandler(); this.eventBus = mock(EventBus.class); this.hazelcastService = mock(HazelcastService.class); this.handler.setEventBus(eventBus); this.handler.setHazelcastService(hazelcastService); } @Test public void shouldSubscribeToDeviceNotifications() throws Exception { String subscriptionId = randomUUID().toString(); String device = randomUUID().toString(); NotificationSubscribeRequest sr = new NotificationSubscribeRequest(subscriptionId, device, null, null); Request request = Request.newBuilder() .withBody(sr) .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); ArgumentCaptor<Subscriber> subscriberCaptor = ArgumentCaptor.forClass(Subscriber.class); ArgumentCaptor<Subscription> subscriptionCaptor = ArgumentCaptor.forClass(Subscription.class); verify(eventBus).subscribe(subscriberCaptor.capture(), subscriptionCaptor.capture()); Subscriber subscriber = subscriberCaptor.getValue(); assertEquals(subscriber.getId(), subscriptionId); assertEquals(subscriber.getCorrelationId(), request.getCorrelationId()); assertEquals(subscriber.getReplyTo(), request.getReplyTo()); Subscription subscription = subscriptionCaptor.getValue(); assertEquals(subscription.getType(), Action.NOTIFICATION_EVENT.name()); assertEquals(subscription.getGuid(), device); assertNull(subscription.getName()); verifyZeroInteractions(hazelcastService); } @Test public void shouldSubscribeToDeviceNotificationsNames() throws Exception { String subscriptionId = randomUUID().toString(); String device = randomUUID().toString(); Set<String> names = Stream.of("a", "b", "c").collect(Collectors.toSet()); NotificationSubscribeRequest sr = new NotificationSubscribeRequest(subscriptionId, device, names, null); Request request = Request.newBuilder() .withBody(sr) .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); ArgumentCaptor<Subscriber> subscriberCaptor = ArgumentCaptor.forClass(Subscriber.class); ArgumentCaptor<Subscription> subscriptionCaptor = ArgumentCaptor.forClass(Subscription.class); verify(eventBus, times(names.size())).subscribe(subscriberCaptor.capture(), subscriptionCaptor.capture()); Set<Subscriber> subscribers = subscriberCaptor.getAllValues().stream().collect(Collectors.toSet()); assertThat(subscribers, hasSize(1)); Subscriber subscriber = subscribers.stream().findFirst().get(); assertEquals(subscriber.getReplyTo(), request.getReplyTo()); assertEquals(subscriber.getId(), subscriptionId); assertEquals(subscriber.getCorrelationId(), request.getCorrelationId()); List<Subscription> subscriptions = subscriptionCaptor.getAllValues(); assertThat(subscriptions, hasSize(names.size())); subscriptions.forEach(subscription -> { assertEquals(subscription.getGuid(), device); assertEquals(subscription.getType(), Action.NOTIFICATION_EVENT.name()); }); Set<String> notificationNames = subscriptions.stream().map(Subscription::getName).collect(Collectors.toSet()); assertThat(notificationNames, hasSize(3)); assertEquals(notificationNames, names); verifyZeroInteractions(hazelcastService); } @Test public void shouldSubscribeAndSearchNotificationsInCache() throws Exception { String subscriptionId = randomUUID().toString(); String device = randomUUID().toString(); Set<String> names = Stream.of("a", "b", "c").collect(Collectors.toSet()); Date timestamp = new Date(); NotificationSubscribeRequest sr = new NotificationSubscribeRequest(subscriptionId, device, names, timestamp); Request request = Request.newBuilder() .withBody(sr) .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); ArgumentCaptor<Subscriber> subscriberCaptor = ArgumentCaptor.forClass(Subscriber.class); ArgumentCaptor<Subscription> subscriptionCaptor = ArgumentCaptor.forClass(Subscription.class); verify(eventBus, times(names.size())).subscribe(subscriberCaptor.capture(), subscriptionCaptor.capture()); Set<Subscriber> subscribers = subscriberCaptor.getAllValues().stream().collect(Collectors.toSet()); assertThat(subscribers, hasSize(1)); Subscriber subscriber = subscribers.stream().findFirst().get(); assertEquals(subscriber.getReplyTo(), request.getReplyTo()); assertEquals(subscriber.getId(), subscriptionId); assertEquals(subscriber.getCorrelationId(), request.getCorrelationId()); List<Subscription> subscriptions = subscriptionCaptor.getAllValues(); assertThat(subscriptions, hasSize(names.size())); subscriptions.forEach(subscription -> { assertEquals(subscription.getGuid(), device); assertEquals(subscription.getType(), Action.NOTIFICATION_EVENT.name()); }); Set<String> notificationNames = subscriptions.stream().map(Subscription::getName).collect(Collectors.toSet()); assertThat(notificationNames, hasSize(3)); assertEquals(notificationNames, names); verify(hazelcastService).find(null, names, Collections.singleton(device), NotificationSubscribeRequestHandler.LIMIT, timestamp, null, null, DeviceNotification.class); } @Test public void shouldThrowIfBodyIsNull() throws Exception { ex.expect(IllegalArgumentException.class); ex.expectMessage("Request body is null"); Request request = Request.newBuilder() .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); } @Test public void shouldThrowIfSubscriptionIdIsNull() throws Exception { ex.expect(IllegalArgumentException.class); ex.expectMessage("Subscription id not provided"); NotificationSubscribeRequest sr = new NotificationSubscribeRequest(null, randomUUID().toString(), null, null); Request request = Request.newBuilder() .withBody(sr) .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); } @Test public void shouldThrowIfDeviceGuidIsNull() throws Exception { ex.expect(IllegalArgumentException.class); ex.expectMessage("Device guid is null"); NotificationSubscribeRequest sr = new NotificationSubscribeRequest(randomUUID().toString(), null, null, null); Request request = Request.newBuilder() .withBody(sr) .withPartitionKey(randomUUID().toString()) .withSingleReply(false) .build(); handler.handle(request); } }