REFACTOR: uses more modern patterns to prevent issues (#27)

This commit is contained in:
Joffrey JAFFEUX 2019-03-20 11:57:07 +01:00 committed by David Taylor
parent 56d11903c0
commit cd53275098
13 changed files with 221 additions and 273 deletions

View File

@ -2,12 +2,9 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
export default Ember.Component.extend({ export default Ember.Component.extend({
classNames: ["channel-details"], classNames: ["channel-details"],
actions: {
refresh: function() {
this.sendAction("refresh");
},
delete(channel) { actions: {
deleteChannel(channel) {
bootbox.confirm( bootbox.confirm(
I18n.t("chat_integration.channel_delete_confirm"), I18n.t("chat_integration.channel_delete_confirm"),
I18n.t("no_value"), I18n.t("no_value"),
@ -16,33 +13,15 @@ export default Ember.Component.extend({
if (result) { if (result) {
channel channel
.destroyRecord() .destroyRecord()
.then(() => { .then(() => this.refresh())
this.send("refresh");
})
.catch(popupAjaxError); .catch(popupAjaxError);
} }
} }
); );
}, },
edit(channel) {
this.sendAction("edit", channel);
},
test(channel) {
this.sendAction("test", channel);
},
createRule(channel) {
this.sendAction("createRule", channel);
},
editRule(rule) { editRule(rule) {
this.sendAction("editRule", rule, this.get("channel")); this.editRuleWithChannel(rule, this.get("channel"));
},
showError(channel) {
this.sendAction("showError", channel);
} }
} }
}); });

View File

@ -20,21 +20,11 @@ export default Ember.Component.extend({
}, },
actions: { actions: {
edit() {
this.sendAction("edit", this.get("rule"));
},
delete(rule) { delete(rule) {
rule rule
.destroyRecord() .destroyRecord()
.then(() => { .then(() => this.refresh())
this.send("refresh");
})
.catch(popupAjaxError); .catch(popupAjaxError);
},
refresh() {
this.sendAction("refresh");
} }
} }
}); });

View File

@ -30,7 +30,7 @@ export default Ember.Controller.extend({
}; };
showModal("admin-plugins-chat-edit-channel", { showModal("admin-plugins-chat-edit-channel", {
model: model, model,
admin: true admin: true
}); });
}, },
@ -39,12 +39,12 @@ export default Ember.Controller.extend({
this.set("modalShowing", true); this.set("modalShowing", true);
const model = { const model = {
channel: channel, channel,
provider: this.get("model.provider") provider: this.get("model.provider")
}; };
showModal("admin-plugins-chat-edit-channel", { showModal("admin-plugins-chat-edit-channel", {
model: model, model,
admin: true admin: true
}); });
}, },
@ -52,7 +52,7 @@ export default Ember.Controller.extend({
testChannel(channel) { testChannel(channel) {
this.set("modalShowing", true); this.set("modalShowing", true);
showModal("admin-plugins-chat-test", { showModal("admin-plugins-chat-test", {
model: { channel: channel }, model: { channel },
admin: true admin: true
}); });
}, },
@ -62,24 +62,25 @@ export default Ember.Controller.extend({
const model = { const model = {
rule: this.store.createRecord("rule", { channel_id: channel.id }), rule: this.store.createRecord("rule", { channel_id: channel.id }),
channel: channel, channel,
provider: this.get("model.provider"), provider: this.get("model.provider"),
groups: this.get("model.groups") groups: this.get("model.groups")
}; };
showModal("admin-plugins-chat-edit-rule", { model: model, admin: true }); showModal("admin-plugins-chat-edit-rule", { model, admin: true });
}, },
editRule(rule, channel) {
editRuleWithChannel(rule, channel) {
this.set("modalShowing", true); this.set("modalShowing", true);
const model = { const model = {
rule: rule, rule,
channel: channel, channel,
provider: this.get("model.provider"), provider: this.get("model.provider"),
groups: this.get("model.groups") groups: this.get("model.groups")
}; };
showModal("admin-plugins-chat-edit-rule", { model: model, admin: true }); showModal("admin-plugins-chat-edit-rule", { model, admin: true });
}, },
showError(channel) { showError(channel) {

View File

@ -25,18 +25,12 @@ export default Ember.Controller.extend(ModalFunctionality, {
}, },
actions: { actions: {
cancel() { save(rule) {
this.send("closeModal");
},
save() {
if (this.get("saveDisabled")) return; if (this.get("saveDisabled")) return;
this.get("model.rule") rule
.save() .save()
.then(() => { .then(() => this.send("closeModal"))
this.send("closeModal");
})
.catch(popupAjaxError); .catch(popupAjaxError);
} }
} }

View File

@ -41,7 +41,7 @@ export default Discourse.Route.extend({
return true; // Continue bubbling up, so the modal actually closes return true; // Continue bubbling up, so the modal actually closes
}, },
refresh() { refreshProvider() {
this.refresh(); this.refresh();
} }
} }

View File

@ -97,14 +97,15 @@
<div class="modal-footer"> <div class="modal-footer">
{{d-button id="save-rule" {{d-button id="save-rule"
class='btn-primary btn-large' class='btn-primary btn-large'
action="save" action="save"
title="chat_integration.edit_rule_modal.save" actionParam=model.rule
label="chat_integration.edit_rule_modal.save" title="chat_integration.edit_rule_modal.save"
disabled=saveDisabled}} label="chat_integration.edit_rule_modal.save"
disabled=saveDisabled}}
{{d-button class="btn-large" {{d-button class="btn-large"
action="cancel" action=(route-action "closeModal")
title="chat_integration.edit_rule_modal.cancel" title="chat_integration.edit_rule_modal.cancel"
label="chat_integration.edit_rule_modal.cancel"}} label="chat_integration.edit_rule_modal.cancel"}}
</div> </div>

View File

@ -15,16 +15,18 @@
<div class="modal-footer"> <div class="modal-footer">
{{#conditional-loading-spinner condition=loading}} {{#conditional-loading-spinner condition=loading}}
{{d-button id="send-test" {{d-button
class='btn-primary btn-large' id="send-test"
action="send" class='btn-primary btn-large'
title="chat_integration.test_modal.send" action=(action "send")
label="chat_integration.test_modal.send" title="chat_integration.test_modal.send"
disabled=sendDisabled}} label="chat_integration.test_modal.send"
disabled=sendDisabled}}
{{d-button class="btn-large" {{d-button
action="closeModal" class="btn-large"
title="chat_integration.test_modal.close" action=(route-action "closeModal")
label="chat_integration.test_modal.close"}} title="chat_integration.test_modal.close"
label="chat_integration.test_modal.close"}}
{{/conditional-loading-spinner}} {{/conditional-loading-spinner}}
</div> </div>

View File

@ -7,24 +7,24 @@
{{#each model.channels as |channel|}} {{#each model.channels as |channel|}}
{{channel-details {{channel-details
channel=channel channel=channel
provider=model.provider provider=model.provider
store=store refresh=(route-action "refreshProvider")
refresh='refresh' editChannel=(action "editChannel")
edit='editChannel' test=(action "testChannel")
test='testChannel' createRule=(action "createRule")
createRule='createRule' editRuleWithChannel=(action "editRuleWithChannel")
editRule='editRule' showError=(action "showError")}}
showError='showError'}}
{{/each}} {{/each}}
<div class="table-footer"> <div class="table-footer">
<div class="pull-right"> <div class="pull-right">
{{d-button id="create-channel" {{d-button
action="createChannel" id="create-channel"
actionParam=model.provider action=(action "createChannel")
icon="plus" actionParam=model.provider
title="chat_integration.create_channel" icon="plus"
label="chat_integration.create_channel"}} title="chat_integration.create_channel"
label="chat_integration.create_channel"}}
</div> </div>
</div> </div>

View File

@ -3,16 +3,20 @@
<div class="span15"> <div class="span15">
<ul class="nav nav-pills"> <ul class="nav nav-pills">
{{#each model as |provider|}} {{#each model as |provider|}}
{{nav-item route='adminPlugins.chat.provider' routeParam=provider.name label=(concat 'chat_integration.provider.' provider.name '.title')}} {{nav-item
route='adminPlugins.chat.provider'
routeParam=provider.name
label=(concat 'chat_integration.provider.' provider.name '.title')}}
{{/each}} {{/each}}
</ul> </ul>
</div> </div>
<div class="pull-right"> <div class="pull-right">
{{d-button action="showSettings" {{d-button
icon="gear" action=(route-action "showSettings")
title="chat_integration.settings" icon="gear"
label="chat_integration.settings"}} title="chat_integration.settings"
label="chat_integration.settings"}}
</div> </div>
</div> </div>

View File

@ -1,6 +1,8 @@
{{#each provider.channel_parameters as |param|}} {{#each provider.channel_parameters as |param|}}
{{#unless param.hidden}} {{#unless param.hidden}}
<span class='field-name'>{{i18n (concat 'chat_integration.provider.' channel.provider '.param.' param.key '.title')}}:</span> <span class='field-name'>
{{i18n (concat 'chat_integration.provider.' channel.provider '.param.' param.key '.title')}}:
</span>
<span class='field-value'>{{get channel.data param.key}}</span> <span class='field-value'>{{get channel.data param.key}}</span>
<br/> <br/>
{{/unless}} {{/unless}}

View File

@ -1,15 +1,36 @@
<div class='channel-header'> <div class='channel-header'>
<div class='pull-right'> <div class='pull-right'>
{{d-button action="edit" actionParam=channel icon="pencil" title="chat_integration.edit_channel" label="chat_integration.edit_channel"}} {{d-button
action=editChannel
actionParam=channel
icon="pencil"
title="chat_integration.edit_channel"
label="chat_integration.edit_channel"}}
{{d-button action="test" actionParam=channel icon="rocket" title="chat_integration.test_channel" label="chat_integration.test_channel" class="btn-chat-test"}} {{d-button
action=test
actionParam=channel
icon="rocket"
title="chat_integration.test_channel"
label="chat_integration.test_channel"
class="btn-chat-test"}}
{{d-button class='cancel' action="delete" actionParam=channel icon="trash" title="chat_integration.delete_channel" label="chat_integration.delete_channel"}} {{d-button
class='cancel'
action=(action "deleteChannel")
actionParam=channel
icon="trash"
title="chat_integration.delete_channel"
label="chat_integration.delete_channel"}}
</div> </div>
<span class='channel-title'> <span class='channel-title'>
{{#if channel.error_key}} {{#if channel.error_key}}
{{d-button action="showError" actionParam=channel class="delete btn-danger" icon="exclamation-triangle"}} {{d-button
action=showError
actionParam=channel
class="delete btn-danger"
icon="exclamation-triangle"}}
{{/if}} {{/if}}
{{channel-data provider=provider channel=channel}} {{channel-data provider=provider channel=channel}}
@ -30,14 +51,15 @@
</tr> </tr>
{{#each channel.rules as |rule|}} {{#each channel.rules as |rule|}}
{{rule-row rule=rule edit='editRule' refresh='refresh'}} {{rule-row rule=rule edit=(action "editRule") refresh=refresh}}
{{/each}} {{/each}}
</table> </table>
</div> </div>
<div class='channel-footer'> <div class='channel-footer'>
<div class='pull-right'> <div class='pull-right'>
{{d-button action="createRule" {{d-button
action=createRule
actionParam=channel actionParam=channel
icon="plus" icon="plus"
title="chat_integration.create_rule" title="chat_integration.create_rule"

View File

@ -28,6 +28,17 @@
{{/if}} {{/if}}
<td> <td>
{{d-button action="edit" actionParam=rule icon="pencil" class="edit" title="chat_integration.rule_table.edit_rule"}} {{d-button
{{d-button action="delete" actionParam=rule icon="trash-o" class="delete" title="chat_integration.rule_table.delete_rule"}} action=edit
actionParam=rule
icon="pencil"
class="edit"
title="chat_integration.rule_table.edit_rule"}}
{{d-button
action=(action "delete")
actionParam=rule
icon="trash-o"
class="delete"
title="chat_integration.rule_table.delete_rule"}}
</td> </td>

View File

@ -7,8 +7,16 @@ acceptance("Chat Integration", {
return [200, { "Content-Type": "text/html; charset=utf-8" }, object]; return [200, { "Content-Type": "text/html; charset=utf-8" }, object];
}; };
const jsonResponse = object => {
return [
200,
{ "Content-Type": "application/json; charset=utf-8" },
object
];
};
server.get("/admin/plugins/chat/providers", () => { server.get("/admin/plugins/chat/providers", () => {
return response({ return jsonResponse({
providers: [ providers: [
{ {
name: "dummy", name: "dummy",
@ -20,7 +28,7 @@ acceptance("Chat Integration", {
}); });
server.get("/admin/plugins/chat/channels", () => { server.get("/admin/plugins/chat/channels", () => {
return response({ return jsonResponse({
channels: [ channels: [
{ {
id: 97, id: 97,
@ -72,94 +80,72 @@ acceptance("Chat Integration", {
}); });
server.get("/groups/search.json", () => { server.get("/groups/search.json", () => {
return response([]); return jsonResponse([]);
}); });
} }
}); });
test("Rules load successfully", assert => { test("Rules load successfully", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { assert.ok(exists("#admin-plugin-chat table"), "it shows the table of rules");
assert.ok(
exists("#admin-plugin-chat table"), assert.equal(
"it shows the table of rules" find("#admin-plugin-chat table tr td")
); .eq(0)
assert.equal( .text()
find("#admin-plugin-chat table tr td") .trim(),
.eq(0) "All posts and replies",
.text() "rule displayed"
.trim(), );
"All posts and replies",
"rule displayed"
);
});
}); });
test("Create channel works", assert => { test("Create channel works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
await click("#create-channel");
andThen(() => { assert.ok(
click("#create-channel"); exists("#chat-integration-edit-channel-modal"),
}); "it displays the modal"
);
assert.ok(
find("#save-channel").prop("disabled"),
"it disables the save button"
);
andThen(() => { await fillIn("#chat-integration-edit-channel-modal input", "#general");
assert.ok(
exists("#chat-integration-edit-channel-modal"),
"it displays the modal"
);
assert.ok(
find("#save-channel").prop("disabled"),
"it disables the save button"
);
fillIn("#chat-integration-edit-channel-modal input", "#general");
});
andThen(() => { assert.ok(
assert.ok( find("#save-channel").prop("disabled") === false,
find("#save-channel").prop("disabled") === false, "it enables the save button"
"it enables the save button" );
);
});
andThen(() => { await click("#save-channel");
click("#save-channel");
});
andThen(() => { assert.ok(
assert.ok( !exists("#chat-integration-edit-channel-modal"),
!exists("#chat-integration-edit-channel-modal"), "modal closes on save"
"modal closes on save" );
);
});
}); });
test("Edit channel works", assert => { test("Edit channel works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
await click(".channel-header button:first");
andThen(() => { assert.ok(
click(".channel-header button:first"); exists("#chat-integration-edit-channel-modal"),
}); "it displays the modal"
);
assert.ok(!find("#save-channel").prop("disabled"), "save is enabled");
andThen(() => { await fillIn("#chat-integration-edit-channel-modal input", " general");
assert.ok(
exists("#chat-integration-edit-channel-modal"),
"it displays the modal"
);
assert.ok(!find("#save-channel").prop("disabled"), "save is enabled");
fillIn("#chat-integration-edit-channel-modal input", " general");
});
andThen(() => { assert.ok(
assert.ok( find("#save-channel").prop("disabled"),
find("#save-channel").prop("disabled"), "it disables the save button"
"it disables the save button" );
);
});
andThen(() => { await fillIn("#chat-integration-edit-channel-modal input", "#random");
fillIn("#chat-integration-edit-channel-modal input", "#random");
});
andThen(() => { andThen(() => {
$("#chat-integration-edit-channel-modal input").trigger( $("#chat-integration-edit-channel-modal input").trigger(
@ -175,132 +161,88 @@ test("Edit channel works", assert => {
}); });
}); });
test("Create rule works", assert => { test("Create rule works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { assert.ok(
assert.ok( exists(".channel-footer button:first"),
exists(".channel-footer button:first"), "create button is displayed"
"create button is displayed" );
);
});
click(".channel-footer button:first"); await click(".channel-footer button:first");
andThen(() => { assert.ok(exists("#chat-integration-edit-rule_modal"), "modal opens on edit");
assert.ok( assert.ok(find("#save-rule").prop("disabled") === false, "save is enabled");
exists("#chat-integration-edit-rule_modal"),
"modal opens on edit"
);
assert.ok(find("#save-rule").prop("disabled") === false, "save is enabled");
});
click("#save-rule"); await click("#save-rule");
andThen(() => { assert.ok(
assert.ok( !exists("#chat-integration-edit-rule_modal"),
!exists("#chat-integration-edit-rule_modal"), "modal closes on save"
"modal closes on save" );
);
});
}); });
test("Edit rule works", assert => { test("Edit rule works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { assert.ok(exists(".edit:first"), "edit button is displayed");
assert.ok(exists(".edit:first"), "edit button is displayed");
});
click(".edit:first"); await click(".edit:first");
andThen(() => { assert.ok(exists("#chat-integration-edit-rule_modal"), "modal opens on edit");
assert.ok( assert.ok(
exists("#chat-integration-edit-rule_modal"), find("#save-rule").prop("disabled") === false,
"modal opens on edit" "it enables the save button"
); );
assert.ok(
find("#save-rule").prop("disabled") === false,
"it enables the save button"
);
});
click("#save-rule"); await click("#save-rule");
andThen(() => { assert.ok(
assert.ok( !exists("#chat-integration-edit-rule_modal"),
!exists("#chat-integration-edit-rule_modal"), "modal closes on save"
"modal closes on save" );
);
});
}); });
test("Delete channel works", function(assert) { test("Delete channel works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { assert.ok(exists(".channel-header button:last"), "delete button exists");
assert.ok(exists(".channel-header button:last"), "delete button exists"); await click(".channel-header button:last");
click(".channel-header button:last");
});
andThen(() => { assert.ok(exists("div.bootbox"), "modal is displayed");
assert.ok(exists("div.bootbox"), "modal is displayed"); await click("div.bootbox .btn-primary");
click("div.bootbox .btn-primary");
});
andThen(() => { assert.ok(exists("div.bootbox") === false, "modal has closed");
assert.ok(exists("div.bootbox") === false, "modal has closed");
});
}); });
test("Delete rule works", function(assert) { test("Delete rule works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { assert.ok(exists(".delete:first"));
assert.ok(exists(".delete:first")); await click(".delete:first");
click(".delete:first");
});
}); });
test("Test channel works", assert => { test("Test channel works", async assert => {
visit("/admin/plugins/chat"); await visit("/admin/plugins/chat");
andThen(() => { await click(".btn-chat-test");
click(".btn-chat-test");
});
andThen(() => { assert.ok(exists("#chat_integration_test_modal"), "it displays the modal");
assert.ok(exists("#chat_integration_test_modal"), "it displays the modal"); assert.ok(find("#send-test").prop("disabled"), "it disables the send button");
assert.ok(
find("#send-test").prop("disabled"),
"it disables the send button"
);
fillIn("#choose-topic-title", "9318");
});
andThen(() => { await fillIn("#choose-topic-title", "9318");
click("#chat_integration_test_modal .radio:first"); await click("#chat_integration_test_modal .radio:first");
});
andThen(() => { assert.ok(
assert.ok( find("#send-test").prop("disabled") === false,
find("#send-test").prop("disabled") === false, "it enables the send button"
"it enables the send button" );
);
});
andThen(() => { await click("#send-test");
click("#send-test");
});
andThen(() => { assert.ok(
assert.ok( exists("#chat_integration_test_modal"),
exists("#chat_integration_test_modal"), "modal doesn't close on send"
"modal doesn't close on send" );
); assert.ok(exists("#modal-alert.alert-success"), "success message displayed");
assert.ok(
exists("#modal-alert.alert-success"),
"success message displayed"
);
});
}); });