1
0
Fork 0

Added an upgrade foxx dialog to the WebInterface

This commit is contained in:
Michael Hackstein 2015-03-03 14:18:35 +01:00
parent 0d09cf0759
commit eca23b3814
19 changed files with 2104 additions and 1406 deletions

View File

@ -2459,7 +2459,6 @@ window.StatisticsCollection = Backbone.Collection.extend({
}());
/*jshint browser: true */
/*jshint unused: false */
/*global Backbone, $, window, setTimeout, Joi, _ */
/*global templateEngine*/

View File

@ -45,13 +45,42 @@
var fs = require("fs");
var defaultThumb = require("/lib/defaultThumbnail").defaultThumb;
controller.extend({
installer: function() {
this.queryParam("mount", mountPoint);
this.queryParam("upgrade", {type: joi.boolean().optional().description(
"Trigger to upgrade the app installed at the mountpoint. Triggers setup."
)});
this.queryParam("replace", {type: joi.boolean().optional().description(
"Trigger to replace the app installed at the mountpoint. Triggers teardown and setup."
)});
}
});
// ------------------------------------------------------------
// SECTION install
// ------------------------------------------------------------
var installApp = function(res, appInfo, mount, options) {
var validateMount = function(req) {
var mount = req.params("mount");
// Validation
mount = decodeURIComponent(mount);
return mount;
};
var installApp = function(req, res, appInfo, options) {
var mount = validateMount(req);
var upgrade = req.params("upgrade") || false;
var replace = req.params("replace") || false;
try {
var app = FoxxManager.install(appInfo, mount, options);
var app;
if (upgrade) {
app = FoxxManager.upgrade(appInfo, mount, options);
} else if (replace) {
app = FoxxManager.replace(appInfo, mount, options);
} else {
app = FoxxManager.install(appInfo, mount, options);
}
var config = FoxxManager.configuration(mount);
res.json({
error: false,
@ -65,12 +94,6 @@
}
};
var validateMount = function(req) {
var mount = req.params("mount");
// Validation
mount = decodeURIComponent(mount);
return mount;
};
/** Install a Foxx from the store
*
* Downloads a Foxx from the store and installs it at the given mount
@ -78,10 +101,9 @@
controller.put("/store", function(req, res) {
var content = JSON.parse(req.requestBody),
name = content.name,
version = content.version,
mount = validateMount(req);
installApp(res, name + ":" + version, mount);
}).queryParam("mount", mountPoint);
version = content.version;
installApp(req, res, name + ":" + version);
}).installer();
/** Install a Foxx from Github
*
@ -90,20 +112,18 @@
controller.put("/git", function (req, res) {
var content = JSON.parse(req.requestBody),
url = content.url,
version = content.version,
mount = validateMount(req);
installApp(res, "git:" + url + ":" + (version || "master"), mount);
}).queryParam("mount", mountPoint);
version = content.version;
installApp(req, res, "git:" + url + ":" + (version || "master"));
}).installer();
/** Generate a new foxx
*
* Generate a new empty foxx on the given mount point
*/
controller.put("/generate", function (req, res) {
var info = JSON.parse(req.requestBody),
mount = validateMount(req);
installApp(res, "EMPTY", mount, info);
}).queryParam("mount", mountPoint);
var info = JSON.parse(req.requestBody);
installApp(req, res, "EMPTY", info);
}).installer();
/** Install a Foxx from temporary zip file
*
@ -113,10 +133,10 @@
controller.put("/zip", function (req, res) {
var content = JSON.parse(req.requestBody),
file = content.zipFile,
mount = validateMount(req),
path = fs.join(fs.getTempPath(), file);
installApp(res, path, mount);
}).queryParam("mount", mountPoint);
installApp(req, res, path);
}).installer();
/** Uninstall a Foxx
*

View File

@ -30,11 +30,19 @@
// Install Foxx from github repo
// info is expected to contain: "url" and "version"
installFromGithub: function (info, mount, callback) {
installFromGithub: function (info, mount, callback, flag) {
var url = "/_admin/aardvark/foxxes/git?mount=" + encodeURIComponent(mount);
if (flag !== undefined) {
if (flag) {
url += "&replace=true";
} else {
url += "&upgrade=true";
}
}
$.ajax({
cache: false,
type: "PUT",
url: "/_admin/aardvark/foxxes/git?mount=" + encodeURIComponent(mount),
url: url,
data: JSON.stringify(info),
contentType: "application/json",
processData: false,
@ -49,11 +57,19 @@
// Install Foxx from arango store
// info is expected to contain: "name" and "version"
installFromStore: function (info, mount, callback) {
installFromStore: function (info, mount, callback, flag) {
var url = "/_admin/aardvark/foxxes/store?mount=" + encodeURIComponent(mount);
if (flag !== undefined) {
if (flag) {
url += "&replace=true";
} else {
url += "&upgrade=true";
}
}
$.ajax({
cache: false,
type: "PUT",
url: "/_admin/aardvark/foxxes/store?mount=" + encodeURIComponent(mount),
url: url,
data: JSON.stringify(info),
contentType: "application/json",
processData: false,
@ -66,11 +82,19 @@
});
},
installFromZip: function(fileName, mount, callback) {
installFromZip: function(fileName, mount, callback, flag) {
var url = "/_admin/aardvark/foxxes/zip?mount=" + encodeURIComponent(mount);
if (flag !== undefined) {
if (flag) {
url += "&replace=true";
} else {
url += "&upgrade=true";
}
}
$.ajax({
cache: false,
type: "PUT",
url: "/_admin/aardvark/foxxes/zip?mount=" + encodeURIComponent(mount),
url: url,
data: JSON.stringify({zipFile: fileName}),
contentType: "application/json",
processData: false,
@ -83,11 +107,19 @@
});
},
generate: function (info, mount, callback) {
generate: function (info, mount, callback, flag) {
var url = "/_admin/aardvark/foxxes/generate?mount=" + encodeURIComponent(mount);
if (flag !== undefined) {
if (flag) {
url += "&replace=true";
} else {
url += "&upgrade=true";
}
}
$.ajax({
cache: false,
type: "PUT",
url: "/_admin/aardvark/foxxes/generate?mount=" + encodeURIComponent(mount),
url: url,
data: JSON.stringify(info),
contentType: "application/json",
processData: false,

View File

@ -59,6 +59,11 @@
initialize: function () {
// This should be the only global object
window.modalView = new window.ModalView();
this.foxxList = new window.FoxxCollection();
window.foxxInstallView = new window.FoxxInstallView({
collection: this.foxxList
});
window.progressView = new window.ProgressView();
var self = this;
@ -78,7 +83,6 @@
arangoHelper.setDocumentStore(this.arangoDocumentStore);
this.arangoCollectionsStore.fetch({async: false});
this.foxxList = new window.FoxxCollection();
this.footerView = new window.FooterView();
this.notificationList = new window.NotificationCollection();

View File

@ -45,6 +45,7 @@
</div>
<div class="header_left">
<input type="button" class="open button-success" disabled="true" value="Open" />
<input id="app-upgrade" type="button" class="upgrade button-warning" value="Upgrade" <%=app.isSystem()?"disabled":"" %>/>
<input id="app-switch-mode" type="button" class="switch-mode button-warning" value="<%=app.get('development')?'Set Pro':'Set Dev'%>" />
<input type="button" class="delete button-danger" value="Delete" <%=app.isSystem()?"disabled":""%> />
</div>

View File

@ -1,17 +1,26 @@
<script id="modalApplicationMount.ejs" type="text/template">
<table>
<tr class="tableRow">
<th class="collectionInfoTh">
Mount*:
</th>
<th class="collectionInfoTh">
<input type="text" id="new-app-mount" value="" placeholder="/my/foxx"></input>
</th>
<th>
<a class="modalTooltips" title="The path the app will be mounted. Has to start with /. Is not allowed to start with /_">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
<% if (content === true) { %>
<th class="collectionInfoTh">
Run teardown:
</th>
<th class="collectionInfoTh">
<input type="checkbox" id="new-app-teardown"></input>
</th>
<% } else { %>
<th class="collectionInfoTh">
Mount*:
</th>
<th class="collectionInfoTh">
<input type="text" id="new-app-mount" value="" placeholder="/my/foxx"></input>
</th>
<th>
<a class="modalTooltips" title="The path the app will be mounted. Has to start with /. Is not allowed to start with /_">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
<% } %>
</tr>
</table>
@ -70,7 +79,7 @@
-->
<tr class="tableRow">
<th class="collectionInfoTh">
Collections*:
Collections:
</th>
<th class="collectionInfoTh">
<input type="hidden" id="new-app-collections" value="" placeholder="Collections"></input>

View File

@ -1,7 +1,7 @@
/*jshint browser: true */
/*jshint strict: false, unused: false */
/*global Backbone, $, window, arangoHelper, templateEngine, Joi, _, modalDialogHelper, alert*/
/*global Backbone, $, window, arangoHelper, templateEngine, Joi, _*/
(function() {
"use strict";
window.ApplicationDetailView = Backbone.View.extend({
el: '#content',
@ -16,6 +16,14 @@
'click #app-setup': 'setup',
'click #app-teardown': 'teardown',
"click #app-scripts": "toggleScripts",
"click #app-upgrade": "upgradeApp"
},
upgradeApp: function() {
var mount = this.model.get("mount");
window.foxxInstallView.upgrade(mount, function() {
window.App.applicationDetail(encodeURIComponent(mount));
});
},
toggleScripts: function() {
@ -48,13 +56,13 @@
},
setup: function() {
this.model.setup(function(data) {
this.model.setup(function() {
});
},
teardown: function() {
this.model.teardown(function(data) {
this.model.teardown(function() {
});
},
@ -67,7 +75,7 @@
$.get(this.appUrl()).success(function () {
$('.open', this.el).prop('disabled', false);
}, this);
}.bind(this));
this.updateConfig();
@ -129,7 +137,7 @@
return;
}
});
this.model.setConfiguration(cfg, function(data) {
this.model.setConfiguration(cfg, function() {
window.modalView.hide();
this.updateConfig();
}.bind(this));

View File

@ -1,15 +1,12 @@
/*jshint browser: true */
/*global require, Backbone, $, window, arangoHelper, templateEngine, Joi, alert, _*/
/*global Backbone, $, window, arangoHelper, templateEngine, _*/
(function() {
"use strict";
var errors = require("internal").errors;
window.ApplicationsView = Backbone.View.extend({
el: '#content',
template: templateEngine.createTemplate("applicationsView.ejs"),
appStoreTemplate: templateEngine.createTemplate("applicationListView.ejs"),
events: {
"click #addApp" : "createInstallModal",
@ -104,282 +101,9 @@
$('#foxxDropdownOut').slideToggle(200);
},
installFoxxFromStore: function(e) {
if (window.modalView.modalTestAll()) {
var mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
var toInstall = $(e.currentTarget).attr("appId");
var version = $(e.currentTarget).attr("appVersion");
this.collection.installFromStore({name: toInstall, version: version}, mount, this.installCallback.bind(this));
}
},
installFoxxFromZip: function(files, data) {
if (window.modalView.modalTestAll()) {
var mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
this.collection.installFromZip(data.filename, mount, this.installCallback.bind(this));
}
},
installCallback: function(result) {
if (result.error === false) {
window.modalView.hide();
this.reload();
} else {
// TODO Error handling properly!
switch(result.errorNum) {
case errors.ERROR_APPLICATION_DOWNLOAD_FAILED.code:
alert("Unable to download application from the given repository.");
break;
default:
alert("Error: " + result.errorNum + ". " + result.errorMessage);
}
}
},
installFoxxFromGithub: function() {
if (window.modalView.modalTestAll()) {
var url, version, mount;
//fetch needed information, need client side verification
//remove name handling on server side because not needed
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
url = window.arangoHelper.escapeHtml($('#repository').val());
version = window.arangoHelper.escapeHtml($('#tag').val());
if (version === '') {
version = "master";
}
var info = {
url: window.arangoHelper.escapeHtml($('#repository').val()),
version: window.arangoHelper.escapeHtml($('#tag').val())
};
try {
Joi.assert(url, Joi.string().regex(/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+$/));
} catch (e) {
return;
}
//send server req through collection
this.collection.installFromGithub(info, mount, this.installCallback.bind(this));
}
},
/* potential error handling
if (info.responseText.indexOf("already used by") > -1) {
alert("Mount path already in use.");
} else if (info.responseText.indexOf("app is not defined") > -1) {
//temp ignore this message, fix needs to be server-side
window.modalView.hide();
self.reload();
} else {
alert(info.statusText);
}
*/
generateNewFoxxApp: function() {
if (window.modalView.modalTestAll()) {
var mount;
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
var info = {
name: window.arangoHelper.escapeHtml($("#new-app-name").val()),
collectionNames: _.map($('#new-app-collections').select2("data"), function(d) {
return window.arangoHelper.escapeHtml(d.text);
}),
// authenticated: window.arangoHelper.escapeHtml($("#new-app-name").val()),
author: window.arangoHelper.escapeHtml($("#new-app-author").val()),
license: window.arangoHelper.escapeHtml($("#new-app-license").val()),
description: window.arangoHelper.escapeHtml($("#new-app-description").val())
};
this.collection.generate(info, mount, this.installCallback.bind(this));
}
},
addAppAction: function() {
var openTab = $(".modal-body .tab-pane.active").attr("id");
switch (openTab) {
case "newApp":
this.generateNewFoxxApp();
break;
case "github":
this.installFoxxFromGithub();
break;
case "zip":
// this.installFoxxFromZip();
break;
default:
}
},
setMountpointValidators: function() {
window.modalView.clearValidators();
window.modalView.modalBindValidation({
id: "new-app-mount",
validateInput: function() {
return [
{
rule: Joi.string().regex(/^(\/(APP[^\/]+|(?!APP)[a-zA-Z0-9_\-%]+))+$/i),
msg: "May not contain /APP"
},
{
rule: Joi.string().regex(/^(\/[a-zA-Z0-9_\-%]+)+$/),
msg: "Can only contain [a-zA-Z0-9_-%]"
},
{
rule: Joi.string().regex(/^\/[^_]/),
msg: "Mountpoints with _ are reserved for internal use"
},
{
rule: Joi.string().regex(/[^\/]$/),
msg: "May not end with /"
},
{
rule: Joi.string().regex(/^\//),
msg: "Has to start with /"
},
{
rule: Joi.string().required().min(2),
msg: "Has to be non-empty"
},
];
}
});
},
setGithubValidators: function() {
window.modalView.modalBindValidation({
id: "repository",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+$/),
msg: "No valid github account and repository."
}
];
}
});
},
setNewAppValidators: function() {
window.modalView.modalBindValidation({
id: "new-app-author",
validateInput: function() {
return [
{
rule: Joi.string().required().min(1),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-name",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z\-_][a-zA-Z0-9\-_]*$/),
msg: "Can only contain a to z, A to Z, 0-9, '-' and '_'."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-description",
validateInput: function() {
return [
{
rule: Joi.string().required().min(1),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-license",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z0-9 \.,;\-]+$/),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalTestAll();
},
switchModalButton: function(event) {
window.modalView.clearValidators();
var openTab = $(event.currentTarget).attr("href").substr(1);
var button = $("#modalButton1");
this.setMountpointValidators();
switch (openTab) {
case "newApp":
button.html("Generate");
button.prop("disabled", false);
this.setNewAppValidators();
break;
case "appstore":
button.html("Install");
button.prop("disabled", true);
break;
case "github":
this.setGithubValidators();
button.html("Install");
button.prop("disabled", false);
break;
case "zip":
button.html("Install");
button.prop("disabled", false);
break;
default:
}
},
createInstallModal: function(event) {
event.preventDefault();
var buttons = [];
var modalEvents = {
"click #infoTab a" : this.switchModalButton.bind(this),
"click .install-app" : this.installFoxxFromStore.bind(this)
};
buttons.push(
window.modalView.createSuccessButton("Generate", this.addAppAction.bind(this))
);
window.modalView.show(
"modalApplicationMount.ejs",
"Install application",
buttons,
undefined,
undefined,
modalEvents
);
$("#new-app-collections").select2({
tags: [],
showSearchBox: false,
minimumResultsForSearch: -1,
width: "336px"
});
$("#upload-foxx-zip").uploadFile({
url: "/_api/upload?multipart=true",
allowedTypes: "zip",
onSuccess: this.installFoxxFromZip.bind(this)
});
var listTempl = this.appStoreTemplate;
$.get("foxxes/fishbowl", function(list) {
var table = $("#appstore-content");
_.each(_.sortBy(list, "name"), function(app) {
table.append(listTempl.render(app));
});
}).fail(function() {
var table = $("#appstore-content");
table.append("<tr><td>Store is not available. ArangoDB is not able to connect to github.com</td></tr>");
});
this.setMountpointValidators();
this.setNewAppValidators();
window.foxxInstallView.install(this.reload.bind(this));
},
render: function() {

View File

@ -0,0 +1,332 @@
/*jshint browser: true */
/*global require, $, Joi, _, alert, templateEngine*/
(function() {
"use strict";
var errors = require("internal").errors;
var appStoreTemplate = templateEngine.createTemplate("applicationListView.ejs");
var FoxxInstallView = function(opts) {
this.collection = opts.collection;
};
var installCallback = function(result) {
if (result.error === false) {
this.collection.fetch({ async: false });
window.modalView.hide();
this.reload();
} else {
// TODO Error handling properly!
switch(result.errorNum) {
case errors.ERROR_APPLICATION_DOWNLOAD_FAILED.code:
alert("Unable to download application from the given repository.");
break;
default:
alert("Error: " + result.errorNum + ". " + result.errorMessage);
}
}
};
var setMountpointValidators = function() {
window.modalView.modalBindValidation({
id: "new-app-mount",
validateInput: function() {
return [
{
rule: Joi.string().regex(/^(\/(APP[^\/]+|(?!APP)[a-zA-Z0-9_\-%]+))+$/i),
msg: "May not contain /APP"
},
{
rule: Joi.string().regex(/^(\/[a-zA-Z0-9_\-%]+)+$/),
msg: "Can only contain [a-zA-Z0-9_-%]"
},
{
rule: Joi.string().regex(/^\/[^_]/),
msg: "Mountpoints with _ are reserved for internal use"
},
{
rule: Joi.string().regex(/[^\/]$/),
msg: "May not end with /"
},
{
rule: Joi.string().regex(/^\//),
msg: "Has to start with /"
},
{
rule: Joi.string().required().min(2),
msg: "Has to be non-empty"
},
];
}
});
};
var setGithubValidators = function() {
window.modalView.modalBindValidation({
id: "repository",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+$/),
msg: "No valid github account and repository."
}
];
}
});
};
var setNewAppValidators = function() {
window.modalView.modalBindValidation({
id: "new-app-author",
validateInput: function() {
return [
{
rule: Joi.string().required().min(1),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-name",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z\-_][a-zA-Z0-9\-_]*$/),
msg: "Can only contain a to z, A to Z, 0-9, '-' and '_'."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-description",
validateInput: function() {
return [
{
rule: Joi.string().required().min(1),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalBindValidation({
id: "new-app-license",
validateInput: function() {
return [
{
rule: Joi.string().required().regex(/^[a-zA-Z0-9 \.,;\-]+$/),
msg: "Has to be non empty."
}
];
}
});
window.modalView.modalTestAll();
};
var switchModalButton = function(event) {
window.modalView.clearValidators();
var openTab = $(event.currentTarget).attr("href").substr(1);
var button = $("#modalButton1");
if (!this._upgrade) {
setMountpointValidators();
}
switch (openTab) {
case "newApp":
button.html("Generate");
button.prop("disabled", false);
setNewAppValidators();
break;
case "appstore":
button.html("Install");
button.prop("disabled", true);
break;
case "github":
setGithubValidators();
button.html("Install");
button.prop("disabled", false);
break;
case "zip":
button.html("Install");
button.prop("disabled", false);
break;
default:
}
};
var installFoxxFromStore = function(e) {
if (window.modalView.modalTestAll()) {
var mount, flag;
if (this._upgrade) {
mount = this.mount;
flag = $('#new-app-teardown').prop("checked");
} else {
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
}
var toInstall = $(e.currentTarget).attr("appId");
var version = $(e.currentTarget).attr("appVersion");
if (flag !== undefined) {
this.collection.installFromStore({name: toInstall, version: version}, mount, installCallback.bind(this), flag);
} else {
this.collection.installFromStore({name: toInstall, version: version}, mount, installCallback.bind(this));
}
}
};
var installFoxxFromZip = function(files, data) {
if (window.modalView.modalTestAll()) {
var mount, flag;
if (this._upgrade) {
mount = this.mount;
flag = $('#new-app-teardown').prop("checked");
} else {
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
}
if (flag !== undefined) {
this.collection.installFromZip(data.filename, mount, installCallback.bind(this), flag);
} else {
this.collection.installFromZip(data.filename, mount, installCallback.bind(this));
}
}
};
var installFoxxFromGithub = function() {
if (window.modalView.modalTestAll()) {
var url, version, mount, flag;
if (this._upgrade) {
mount = this.mount;
flag = $('#new-app-teardown').prop("checked");
} else {
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
}
url = window.arangoHelper.escapeHtml($('#repository').val());
version = window.arangoHelper.escapeHtml($('#tag').val());
if (version === '') {
version = "master";
}
var info = {
url: window.arangoHelper.escapeHtml($('#repository').val()),
version: window.arangoHelper.escapeHtml($('#tag').val())
};
try {
Joi.assert(url, Joi.string().regex(/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+$/));
} catch (e) {
return;
}
//send server req through collection
if (flag !== undefined) {
this.collection.installFromGithub(info, mount, installCallback.bind(this), flag);
} else {
this.collection.installFromGithub(info, mount, installCallback.bind(this));
}
}
};
var generateNewFoxxApp = function() {
if (window.modalView.modalTestAll()) {
var mount, flag;
if (this._upgrade) {
mount = this.mount;
flag = $('#new-app-teardown').prop("checked");
} else {
mount = window.arangoHelper.escapeHtml($('#new-app-mount').val());
}
var info = {
name: window.arangoHelper.escapeHtml($("#new-app-name").val()),
collectionNames: _.map($('#new-app-collections').select2("data"), function(d) {
return window.arangoHelper.escapeHtml(d.text);
}),
// authenticated: window.arangoHelper.escapeHtml($("#new-app-name").val()),
author: window.arangoHelper.escapeHtml($("#new-app-author").val()),
license: window.arangoHelper.escapeHtml($("#new-app-license").val()),
description: window.arangoHelper.escapeHtml($("#new-app-description").val())
};
if (flag !== undefined) {
this.collection.generate(info, mount, installCallback.bind(this), flag);
} else {
this.collection.generate(info, mount, installCallback.bind(this));
}
}
};
var addAppAction = function() {
var openTab = $(".modal-body .tab-pane.active").attr("id");
switch (openTab) {
case "newApp":
generateNewFoxxApp.apply(this);
break;
case "github":
installFoxxFromGithub.apply(this);
break;
case "zip":
break;
default:
}
};
var render = function(scope, upgrade) {
var buttons = [];
var modalEvents = {
"click #infoTab a" : switchModalButton.bind(scope),
"click .install-app" : installFoxxFromStore.bind(scope)
};
buttons.push(
window.modalView.createSuccessButton("Generate", addAppAction.bind(scope))
);
window.modalView.show(
"modalApplicationMount.ejs",
"Install application",
buttons,
upgrade,
undefined,
modalEvents
);
$("#new-app-collections").select2({
tags: [],
showSearchBox: false,
minimumResultsForSearch: -1,
width: "336px"
});
$("#upload-foxx-zip").uploadFile({
url: "/_api/upload?multipart=true",
allowedTypes: "zip",
onSuccess: installFoxxFromZip.bind(scope)
});
$.get("foxxes/fishbowl", function(list) {
var table = $("#appstore-content");
_.each(_.sortBy(list, "name"), function(app) {
table.append(appStoreTemplate.render(app));
});
}).fail(function() {
var table = $("#appstore-content");
table.append("<tr><td>Store is not available. ArangoDB is not able to connect to github.com</td></tr>");
});
};
FoxxInstallView.prototype.install = function(callback) {
this.reload = callback;
this._upgrade = false;
delete this.mount;
render(this, false);
window.modalView.clearValidators();
setMountpointValidators();
setNewAppValidators();
};
FoxxInstallView.prototype.upgrade = function(mount, callback) {
this.reload = callback;
this._upgrade = true;
this.mount = mount;
render(this, true);
window.modalView.clearValidators();
setNewAppValidators();
};
window.FoxxInstallView = FoxxInstallView;
}());

View File

@ -1,5 +1,4 @@
/*jshint browser: true */
/*jshint unused: false */
/*global Backbone, $, window, setTimeout, Joi, _ */
/*global templateEngine*/

View File

@ -30,12 +30,10 @@
position: absolute;
width: 120px;
input.delete {
margin-top: (160px - 3 * 30px) / 2;
}
input.delete,
input.upgrade,
input.switch-mode {
margin-top: (160px - 3 * 30px) / 2;
margin-top: (160px - 4 * 30px) / 3;
}
}

View File

@ -72,6 +72,7 @@
"test/specs/views/applicationsViewSpec.js",
"test/specs/views/applicationDetailViewSpec.js",
"test/specs/views/modalViewSpec.js",
"test/specs/views/installFoxxViewSpec.js",
"test/specs/views/editListEntryViewSpec.js",
"test/specs/views/collectionsViewSpec.js",
"test/specs/views/collectionsItemViewSpec.js",

View File

@ -71,6 +71,7 @@
"test/specs/views/apiViewSpec.js",
"test/specs/views/modalViewSpec.js",
"test/specs/views/foxxInstallViewSpec.js",
"test/specs/views/editListEntryViewSpec.js",
"test/specs/views/collectionsViewSpec.js",
"test/specs/views/collectionsItemViewSpec.js",

View File

@ -179,6 +179,248 @@
});
});
describe("upgrading apps", function() {
it("should generate an app", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
name: "My App",
author: "ArangoDB",
description: "Description of the App",
license: "Apache 2",
collectionNames: ["first", "second"]
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.generate(info, mount, function() {
calledBack = true;
}, false);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/generate?mount=" + encodeURIComponent(mount) + "&upgrade=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from github", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
url: "arangodb/itzpapalotl",
version: "1.2.0"
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromGithub(info, mount, function() {
calledBack = true;
}, false);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/git?mount=" + encodeURIComponent(mount) + "&upgrade=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from store", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
name: "itzpapalotl",
version: "1.2.0"
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromStore(info, mount, function() {
calledBack = true;
}, false);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/store?mount=" + encodeURIComponent(mount) + "&upgrade=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from an uploaded zip", function() {
var calledBack, info, mount;
runs(function() {
var fileName = "uploads/tmp-123.zip";
calledBack = false;
info = {
zipFile: fileName,
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromZip(fileName, mount, function() {
calledBack = true;
}, false);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/zip?mount=" + encodeURIComponent(mount) + "&upgrade=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
});
describe("replacing apps", function() {
it("should generate an app", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
name: "My App",
author: "ArangoDB",
description: "Description of the App",
license: "Apache 2",
collectionNames: ["first", "second"]
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.generate(info, mount, function() {
calledBack = true;
}, true);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/generate?mount=" + encodeURIComponent(mount) + "&replace=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from github", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
url: "arangodb/itzpapalotl",
version: "1.2.0"
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromGithub(info, mount, function() {
calledBack = true;
}, true);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/git?mount=" + encodeURIComponent(mount) + "&replace=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from store", function() {
var calledBack, info, mount;
runs(function() {
calledBack = false;
info = {
name: "itzpapalotl",
version: "1.2.0"
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromStore(info, mount, function() {
calledBack = true;
}, true);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/store?mount=" + encodeURIComponent(mount) + "&replace=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
it("should install an app from an uploaded zip", function() {
var calledBack, info, mount;
runs(function() {
var fileName = "uploads/tmp-123.zip";
calledBack = false;
info = {
zipFile: fileName,
};
mount = "/my/app";
spyOn($, "ajax").andCallFake(function(opts) {
opts.success();
});
col.installFromZip(fileName, mount, function() {
calledBack = true;
}, true);
});
waitsFor(function() {
return calledBack;
}, 750);
runs(function() {
var url = "/_admin/aardvark/foxxes/zip?mount=" + encodeURIComponent(mount) + "&replace=true";
validateRequest(url, "PUT", JSON.stringify(info));
});
});
});
});
}());

View File

@ -33,6 +33,7 @@
// Spy on all views that are initialized by startup
beforeEach(function () {
window.CreateDummyForObject(window, "FoxxInstallView");
naviDummy = {
id: "navi",
render: function () {
@ -253,6 +254,7 @@
afterEach(function() {
// Remove all global values the router has created.
delete window.modalView;
delete window.foxxInstallView;
delete window.progressView;
});
@ -265,6 +267,13 @@
r = new window.Router();
});
it("should create the foxx installer", function() {
expect(window.FoxxInstallView).toHaveBeenCalledWith({
collection: foxxDummy
});
expect(window.foxxInstallView).toBeDefined();
});
it("should trigger the version check", function() {
expect(window.checkVersion).toHaveBeenCalled();
expect(window.checkVersion.callCount).toEqual(1);

View File

@ -53,7 +53,9 @@
deleteButton = $("input.delete");
openButton = $("input.open");
window.CreateDummyForObject(window, "Router");
window.CreateDummyForObject(window, "FoxxInstallView");
window.App = new window.Router();
window.foxxInstallView = new window.FoxxInstallView();
spyOn(window.App, "navigate");
});
@ -394,6 +396,21 @@
$(button).click();
expect(appDummy.teardown).toHaveBeenCalledWith(jasmine.any(Function));
});
it("should offer upgrading the app", function() {
spyOn(window.foxxInstallView, "upgrade").andCallFake(function(mount, cb) {
expect(mount).toEqual(appDummy.get("mount"));
expect(cb).toEqual(jasmine.any(Function));
cb();
});
spyOn(window.App, "applicationDetail");
$("#app-upgrade").click();
expect(window.foxxInstallView.upgrade).toHaveBeenCalled();
expect(window.App.applicationDetail).toHaveBeenCalledWith(
encodeURIComponent(view.model.get('mount'))
);
});
/*
describe("edit a foxx", function() {

View File

@ -21,11 +21,15 @@
document.body.appendChild(div);
window.CreateDummyForObject(window, "FoxxCollection");
listDummy = new window.FoxxCollection();
window.foxxInstallView = new window.FoxxInstallView({
collection: listDummy
});
});
afterEach(function() {
document.body.removeChild(div);
delete window.modalView;
delete window.foxxInstallView;
document.body.removeChild(modalDiv);
});
@ -68,6 +72,7 @@
view = new window.ApplicationsView({
collection: listDummy
});
spyOn(view, "reload");
runs(function () {
$("#addApp").click();
@ -123,7 +128,6 @@
$("#new-app-license").val(license);
$("#new-app-mount").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
spyOn(view, "reload");
$(generateButton).click();
});
@ -157,7 +161,6 @@
expect($("#appstore-content").children().length).toEqual(2);
button = $("#appstore-content .install-app[appId='" + storeApp + "']");
expect(button.length).toEqual(1);
spyOn(view, "reload");
button.click();
});
@ -195,7 +198,6 @@
$("#tag").val(version);
$("#new-app-mount").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
spyOn(view, "reload");
$(generateButton).click();
});
@ -224,7 +226,6 @@
});
});
$("#new-app-mount").val(mount);
spyOn(view, "reload");
uploadCallback(["app.zip"], {filename: fileName});
});

View File

@ -0,0 +1,618 @@
/*jshint browser: true */
/*global describe, beforeEach, afterEach, it, spyOn, expect*/
/*global runs, waitsFor, jasmine*/
/*global $*/
(function() {
"use strict";
describe("Foxx Install View", function() {
var view, listDummy, closeButton, generateButton, modalDiv,
uploadCallback, storeApp, storeAppVersion;
beforeEach(function() {
modalDiv = document.createElement("div");
modalDiv.id = "modalPlaceholder";
document.body.appendChild(modalDiv);
window.modalView = new window.ModalView();
closeButton = "#modalButton0";
generateButton = "#modalButton1";
window.CreateDummyForObject(window, "FoxxCollection");
listDummy = new window.FoxxCollection();
view = new window.FoxxInstallView({
collection: listDummy
});
storeApp = "Online App";
storeAppVersion = "2.1.1";
spyOn(listDummy, "fetch").andCallFake(function(opts) {
opts.success();
});
spyOn(listDummy, "each");
spyOn(listDummy, "sort");
spyOn($.fn, "uploadFile").andCallFake(function(opts) {
expect(opts.url).toEqual("/_api/upload?multipart=true");
expect(opts.allowedTypes).toEqual("zip");
expect(opts.onSuccess).toEqual(jasmine.any(Function));
uploadCallback = opts.onSuccess;
});
spyOn($, "get").andCallFake(function(url, callback) {
expect(url).toEqual("foxxes/fishbowl");
callback([
{
name: "MyApp",
author: "ArangoDB",
description: "Description of the app",
latestVersion: "1.1.0"
},{
name: storeApp,
author: "ArangoDB",
description: "Description of the other app",
latestVersion: storeAppVersion
}
]);
return {
fail: function() {}
};
});
});
afterEach(function() {
delete window.modalView;
document.body.removeChild(modalDiv);
});
describe("Adding a new App", function() {
var spyFunc;
beforeEach(function() {
runs(function () {
spyFunc = jasmine.createSpy("reload");
view.install(spyFunc);
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "block";
}, "The Add App dialog should be shown", 750);
});
it("should open and close the install dialog", function() {
runs(function() {
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("should offer the mountpoint input but not the run teardown", function() {
runs(function() {
expect($("#new-app-mount").length).toEqual(1);
expect($("#new-app-teardown").length).toEqual(0);
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("should generate an empty app", function() {
var mount, author, name, desc, license, expectedInfo;
runs(function() {
$("#tab-new").click();
spyOn(listDummy, "generate").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
mount = "/my/application";
author = "ArangoDB";
name = "MyApp";
desc = "My new app";
license = "Apache 2";
expectedInfo = {
author: author,
name: name,
description: desc,
license: license,
collectionNames: []
};
expect($(generateButton).prop("disabled")).toBeTruthy();
$("#new-app-mount").val(mount);
$("#new-app-author").val(author);
$("#new-app-name").val(name);
$("#new-app-description").val(desc);
$("#new-app-license").val(license);
$("#new-app-mount").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.generate).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function)
);
});
});
it("should install an app from the store", function() {
var mount;
runs(function() {
var button;
mount = "/my/application";
$("#tab-store").click();
$("#new-app-mount").val(mount);
$("#new-app-mount").keyup();
spyOn(listDummy, "installFromStore").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
expect($("#appstore-content").children().length).toEqual(2);
button = $("#appstore-content .install-app[appId='" + storeApp + "']");
expect(button.length).toEqual(1);
button.click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromStore).toHaveBeenCalledWith(
{name: storeApp, version: storeAppVersion}, mount, jasmine.any(Function)
);
});
});
it("should install an app from github", function() {
var repository, version, mount, expectedInfo;
runs(function() {
$("#tab-git").click();
spyOn(listDummy, "installFromGithub").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
repository = "arangodb/itzpapalotl";
version = "1.2.0";
mount = "/my/application";
expectedInfo = {
url: repository,
version: version
};
$("#new-app-mount").val(mount);
$("#repository").val(repository);
$("#tag").val(version);
$("#new-app-mount").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromGithub).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function)
);
});
});
it("should install an app from zip file", function() {
var fileName = "/tmp/upload-12345.zip";
var mount = "/my/application";
runs(function() {
$("#tab-zip").click();
spyOn(listDummy, "installFromZip").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
$("#new-app-mount").val(mount);
uploadCallback(["app.zip"], {filename: fileName});
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromZip).toHaveBeenCalledWith(
fileName, mount, jasmine.any(Function)
);
});
});
});
describe("Upgradeing App", function() {
var spyFunc, mount;
beforeEach(function() {
runs(function () {
mount = "/my/application";
spyFunc = jasmine.createSpy("reload");
view.upgrade(mount, spyFunc);
$("#new-app-teardown").prop("checked", false);
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "block";
}, "The Add App dialog should be shown", 750);
});
it("should open and close the dialog", function() {
runs(function() {
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("should not offer the mountpoint input but the run teardown", function() {
runs(function() {
expect($("#new-app-mount").length).toEqual(0);
expect($("#new-app-teardown").length).toEqual(1);
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("generate an empty app", function() {
var author, name, desc, license, expectedInfo;
runs(function() {
$("#tab-new").click();
spyOn(listDummy, "generate").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
author = "ArangoDB";
name = "MyApp";
desc = "My new app";
license = "Apache 2";
expectedInfo = {
author: author,
name: name,
description: desc,
license: license,
collectionNames: []
};
expect($(generateButton).prop("disabled")).toBeTruthy();
$("#new-app-author").val(author);
$("#new-app-name").val(name);
$("#new-app-description").val(desc);
$("#new-app-license").val(license);
$("#new-app-license").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.generate).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function), false
);
});
});
it("an app from the store", function() {
runs(function() {
var button;
$("#tab-store").click();
spyOn(listDummy, "installFromStore").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
expect($("#appstore-content").children().length).toEqual(2);
button = $("#appstore-content .install-app[appId='" + storeApp + "']");
expect(button.length).toEqual(1);
button.click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromStore).toHaveBeenCalledWith(
{name: storeApp, version: storeAppVersion}, mount, jasmine.any(Function), false
);
});
});
it("an app from github", function() {
var repository, version, expectedInfo;
runs(function() {
$("#tab-git").click();
spyOn(listDummy, "installFromGithub").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
repository = "arangodb/itzpapalotl";
version = "1.2.0";
expectedInfo = {
url: repository,
version: version
};
$("#repository").val(repository);
$("#tag").val(version).keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromGithub).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function), false
);
});
});
it("an app from zip file", function() {
var fileName = "/tmp/upload-12345.zip";
runs(function() {
$("#tab-zip").click();
spyOn(listDummy, "installFromZip").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
uploadCallback(["app.zip"], {filename: fileName});
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromZip).toHaveBeenCalledWith(
fileName, mount, jasmine.any(Function), false
);
});
});
});
describe("Replacing App", function() {
var spyFunc, mount;
beforeEach(function() {
runs(function () {
mount = "/my/application";
spyFunc = jasmine.createSpy("reload");
view.upgrade(mount, spyFunc);
$("#new-app-teardown").prop("checked", true);
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "block";
}, "The Add App dialog should be shown", 750);
});
it("should open and close the dialog", function() {
runs(function() {
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("should not offer the mountpoint input but the run teardown", function() {
runs(function() {
expect($("#new-app-mount").length).toEqual(0);
expect($("#new-app-teardown").length).toEqual(1);
$(closeButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
});
it("generate an empty app", function() {
var author, name, desc, license, expectedInfo;
runs(function() {
$("#tab-new").click();
spyOn(listDummy, "generate").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
author = "ArangoDB";
name = "MyApp";
desc = "My new app";
license = "Apache 2";
expectedInfo = {
author: author,
name: name,
description: desc,
license: license,
collectionNames: []
};
expect($(generateButton).prop("disabled")).toBeTruthy();
$("#new-app-author").val(author);
$("#new-app-name").val(name);
$("#new-app-description").val(desc);
$("#new-app-license").val(license);
$("#new-app-license").keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.generate).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function), true
);
});
});
it("an app from the store", function() {
runs(function() {
var button;
$("#tab-store").click();
spyOn(listDummy, "installFromStore").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
expect($("#appstore-content").children().length).toEqual(2);
button = $("#appstore-content .install-app[appId='" + storeApp + "']");
expect(button.length).toEqual(1);
button.click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromStore).toHaveBeenCalledWith(
{name: storeApp, version: storeAppVersion}, mount, jasmine.any(Function), true
);
});
});
it("an app from github", function() {
var repository, version, expectedInfo;
runs(function() {
$("#tab-git").click();
spyOn(listDummy, "installFromGithub").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
repository = "arangodb/itzpapalotl";
version = "1.2.0";
expectedInfo = {
url: repository,
version: version
};
$("#repository").val(repository);
$("#tag").val(version).keyup();
expect($(generateButton).prop("disabled")).toBeFalsy();
$(generateButton).click();
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromGithub).toHaveBeenCalledWith(
expectedInfo, mount, jasmine.any(Function), true
);
});
});
it("an app from zip file", function() {
var fileName = "/tmp/upload-12345.zip";
runs(function() {
$("#tab-zip").click();
spyOn(listDummy, "installFromZip").andCallFake(function(i, m, callback) {
callback({
error: false
});
});
uploadCallback(["app.zip"], {filename: fileName});
});
waitsFor(function () {
return $("#modal-dialog").css("display") === "none";
}, "The Add App dialog should be hidden.", 750);
runs(function() {
expect(spyFunc).toHaveBeenCalled();
expect(listDummy.installFromZip).toHaveBeenCalledWith(
fileName, mount, jasmine.any(Function), true
);
});
});
});
});
}());