package cc.blynk.integration.tcp;
import cc.blynk.integration.IntegrationBase;
import cc.blynk.integration.model.tcp.ClientPair;
import cc.blynk.server.Holder;
import cc.blynk.server.application.AppServer;
import cc.blynk.server.core.BaseServer;
import cc.blynk.server.core.model.DashBoard;
import cc.blynk.server.core.model.Profile;
import cc.blynk.server.core.model.auth.App;
import cc.blynk.server.core.model.device.Device;
import cc.blynk.server.core.model.device.Status;
import cc.blynk.server.core.protocol.model.messages.ResponseMessage;
import cc.blynk.server.db.model.FlashedToken;
import cc.blynk.server.hardware.HardwareServer;
import cc.blynk.server.notifications.mail.QrHolder;
import cc.blynk.utils.JsonParser;
import net.glxn.qrgen.core.image.ImageType;
import net.glxn.qrgen.javase.QRCode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import static cc.blynk.server.core.protocol.enums.Response.ILLEGAL_COMMAND;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 2/2/2015.
*
*/
@RunWith(MockitoJUnitRunner.class)
public class PublishingPreviewFlow extends IntegrationBase {
private BaseServer appServer;
private BaseServer hardwareServer;
private ClientPair clientPair;
@Before
public void init() throws Exception {
holder = new Holder(properties, twitterWrapper, mailWrapper, gcmWrapper, smsWrapper, "db-test.properties");
assertNotNull(holder.dbManager.getConnection());
this.hardwareServer = new HardwareServer(holder).start();
this.appServer = new AppServer(holder).start();
this.clientPair = initAppAndHardPair();
holder.dbManager.executeSQL("DELETE FROM flashed_tokens");
}
@After
public void shutdown() {
this.appServer.close();
this.hardwareServer.close();
this.clientPair.stop();
}
@Test
public void testGetProjectByToken() throws Exception {
clientPair.appClient.send("createApp {\"theme\":\"Blynk\",\"provisionType\":\"STATIC\",\"color\":0,\"name\":\"AppPreview\",\"icon\":\"myIcon\",\"projectIds\":[1]}");
App app = JsonParser.parseApp(clientPair.appClient.getBody());
assertNotNull(app);
assertNotNull(app.id);
clientPair.appClient.reset();
clientPair.appClient.send("getDevices 1");
String response = clientPair.appClient.getBody();
Device[] devices = JsonParser.mapper.readValue(response, Device[].class);
assertEquals(1, devices.length);
clientPair.appClient.send("emailQr 1\0" + app.id);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
QrHolder[] qrHolders = makeQRs(DEFAULT_TEST_USER, devices, 1, false);
StringBuilder sb = new StringBuilder();
qrHolders[0].attach(sb);
verify(mailWrapper, timeout(500)).sendWithAttachment(eq(DEFAULT_TEST_USER), eq("AppPreview" + " - App details"), eq(holder.limits.STATIC_MAIL_BODY.replace("{device_section}", sb.toString())), eq(qrHolders));
clientPair.appClient.send("getProjectByToken " + qrHolders[0].token);
String body = clientPair.appClient.getBody(3);
assertNotNull(body);
DashBoard dashBoard = JsonParser.parseDashboard(body);
assertNotNull(dashBoard);
assertEquals(1, dashBoard.id);
}
@Test
public void testSendStaticEmailForAppPublish() throws Exception {
clientPair.appClient.send("createApp {\"theme\":\"Blynk\",\"provisionType\":\"STATIC\",\"color\":0,\"name\":\"AppPreview\",\"icon\":\"myIcon\",\"projectIds\":[1]}");
App app = JsonParser.parseApp(clientPair.appClient.getBody());
assertNotNull(app);
assertNotNull(app.id);
clientPair.appClient.reset();
clientPair.appClient.send("getDevices 1");
String response = clientPair.appClient.getBody();
Device[] devices = JsonParser.mapper.readValue(response, Device[].class);
assertEquals(1, devices.length);
clientPair.appClient.send("emailQr 1\0" + app.id);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
QrHolder[] qrHolders = makeQRs(DEFAULT_TEST_USER, devices, 1, false);
StringBuilder sb = new StringBuilder();
qrHolders[0].attach(sb);
verify(mailWrapper, timeout(500)).sendWithAttachment(eq(DEFAULT_TEST_USER), eq("AppPreview" + " - App details"), eq(holder.limits.STATIC_MAIL_BODY.replace("{device_section}", sb.toString())), eq(qrHolders));
FlashedToken flashedToken = holder.dbManager.selectFlashedToken(qrHolders[0].token);
assertNotNull(flashedToken);
assertEquals(flashedToken.appId, app.id);
assertEquals(1, flashedToken.dashId);
assertEquals(0, flashedToken.deviceId);
assertEquals(qrHolders[0].token, flashedToken.token);
assertEquals(false, flashedToken.isActivated);
}
@Test
public void testSendDynamicEmailForAppPublish() throws Exception {
clientPair.appClient.send("createApp {\"theme\":\"Blynk\",\"provisionType\":\"DYNAMIC\",\"color\":0,\"name\":\"AppPreview\",\"icon\":\"myIcon\",\"projectIds\":[1]}");
App app = JsonParser.parseApp(clientPair.appClient.getBody());
assertNotNull(app);
assertNotNull(app.id);
clientPair.appClient.reset();
clientPair.appClient.send("getDevices 1");
String response = clientPair.appClient.getBody();
Device[] devices = JsonParser.mapper.readValue(response, Device[].class);
assertEquals(1, devices.length);
clientPair.appClient.send("emailQr 1\0" + app.id);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
QrHolder[] qrHolders = makeQRs(DEFAULT_TEST_USER, devices, 1, false);
verify(mailWrapper, timeout(500)).sendWithAttachment(eq(DEFAULT_TEST_USER), eq("AppPreview" + " - App details"), eq(holder.limits.DYNAMIC_MAIL_BODY), eq(qrHolders));
}
@Test
public void testDeleteWorksForPreviewApp() throws Exception {
clientPair.appClient.send("createApp {\"theme\":\"Blynk\",\"provisionType\":\"STATIC\",\"color\":0,\"name\":\"AppPreview\",\"icon\":\"myIcon\",\"projectIds\":[1]}");
App app = JsonParser.parseApp(clientPair.appClient.getBody());
assertNotNull(app);
assertNotNull(app.id);
clientPair.appClient.reset();
clientPair.appClient.send("getDevices 1");
String response = clientPair.appClient.getBody();
Device[] devices = JsonParser.mapper.readValue(response, Device[].class);
assertEquals(1, devices.length);
clientPair.appClient.send("emailQr 1\0" + app.id);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
QrHolder[] qrHolders = makeQRs(DEFAULT_TEST_USER, devices, 1, false);
StringBuilder sb = new StringBuilder();
qrHolders[0].attach(sb);
verify(mailWrapper, timeout(500)).sendWithAttachment(eq(DEFAULT_TEST_USER), eq("AppPreview" + " - App details"), eq(holder.limits.STATIC_MAIL_BODY.replace("{device_section}", sb.toString())), eq(qrHolders));
clientPair.appClient.send("loadProfileGzipped " + qrHolders[0].token + " " + qrHolders[0].dashId + " " + DEFAULT_TEST_USER);
DashBoard dashBoard = JsonParser.parseDashboard(clientPair.appClient.getBody(3));
assertNotNull(dashBoard);
assertNotNull(dashBoard.devices);
assertNull(dashBoard.devices[0].token);
assertNull(dashBoard.devices[0].lastLoggedIP);
assertEquals(0, dashBoard.devices[0].disconnectTime);
assertEquals(Status.OFFLINE, dashBoard.devices[0].status);
dashBoard.id = 2;
dashBoard.parentId = 1;
dashBoard.isPreview = true;
clientPair.appClient.send("createDash " + dashBoard.toString());
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(4)));
clientPair.appClient.send("deleteDash 2");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(5)));
clientPair.appClient.send("loadProfileGzipped 1");
dashBoard = JsonParser.parseDashboard(clientPair.appClient.getBody(6));
assertNotNull(dashBoard);
assertEquals(1, dashBoard.id);
clientPair.appClient.send("loadProfileGzipped 2");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(7, ILLEGAL_COMMAND)));
}
@Test
public void testDeleteWorksForParentOfPreviewApp() throws Exception {
clientPair.appClient.send("createApp {\"theme\":\"Blynk\",\"provisionType\":\"STATIC\",\"color\":0,\"name\":\"AppPreview\",\"icon\":\"myIcon\",\"projectIds\":[1]}");
App app = JsonParser.parseApp(clientPair.appClient.getBody());
assertNotNull(app);
assertNotNull(app.id);
clientPair.appClient.reset();
clientPair.appClient.send("getDevices 1");
String response = clientPair.appClient.getBody();
Device[] devices = JsonParser.mapper.readValue(response, Device[].class);
assertEquals(1, devices.length);
clientPair.appClient.send("emailQr 1\0" + app.id);
verify(clientPair.appClient.responseMock, timeout(1000)).channelRead(any(), eq(ok(2)));
QrHolder[] qrHolders = makeQRs(DEFAULT_TEST_USER, devices, 1, false);
StringBuilder sb = new StringBuilder();
qrHolders[0].attach(sb);
verify(mailWrapper, timeout(500)).sendWithAttachment(eq(DEFAULT_TEST_USER), eq("AppPreview" + " - App details"), eq(holder.limits.STATIC_MAIL_BODY.replace("{device_section}", sb.toString())), eq(qrHolders));
clientPair.appClient.send("loadProfileGzipped " + qrHolders[0].token + " " + qrHolders[0].dashId + " " + DEFAULT_TEST_USER);
DashBoard dashBoard = JsonParser.parseDashboard(clientPair.appClient.getBody(3));
assertNotNull(dashBoard);
assertNotNull(dashBoard.devices);
assertNull(dashBoard.devices[0].token);
assertNull(dashBoard.devices[0].lastLoggedIP);
assertEquals(0, dashBoard.devices[0].disconnectTime);
assertEquals(Status.OFFLINE, dashBoard.devices[0].status);
dashBoard.id = 2;
dashBoard.parentId = 1;
dashBoard.isPreview = true;
clientPair.appClient.send("createDash " + dashBoard.toString());
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(4)));
clientPair.appClient.send("deleteDash 1");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(5)));
clientPair.appClient.send("loadProfileGzipped");
Profile profile = JsonParser.parseProfileFromString(clientPair.appClient.getBody(6));
assertNotNull(profile);
assertNotNull(profile.dashBoards);
assertEquals(1, profile.dashBoards.length);
clientPair.appClient.send("loadProfileGzipped 2");
response = clientPair.appClient.getBody(7);
assertNotNull(response);
}
private QrHolder[] makeQRs(String to, Device[] devices, int dashId, boolean onlyFirst) throws Exception {
QrHolder[] qrHolders = new QrHolder[devices.length];
List<FlashedToken> flashedTokens = getAllTokens();
int i = 0;
for (Device device : devices) {
if (onlyFirst && i > 0) {
break;
}
String newToken = flashedTokens.get(i).token;
qrHolders[i] = new QrHolder(1, device.id, device.name, newToken, QRCode.from(newToken).to(ImageType.JPG).stream().toByteArray());
i++;
}
return qrHolders;
}
private List<FlashedToken> getAllTokens() throws Exception {
List<FlashedToken> list = new ArrayList<>();
try (Connection connection = holder.dbManager.getConnection();
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("select * from flashed_tokens")) {
int i = 0;
if (rs.next()) {
list.add(new FlashedToken(rs.getString("token"), rs.getString("app_name"),
rs.getString("email"), rs.getInt("project_id"), rs.getInt("device_id"),
rs.getBoolean("is_activated"), rs.getDate("ts")
));
}
connection.commit();
}
return list;
}
}