diff --git a/ui/jstests/test_manage_taxonomies.jsx b/ui/jstests/test_manage_taxonomies.jsx index 5f43eac8..ba0c0038 100644 --- a/ui/jstests/test_manage_taxonomies.jsx +++ b/ui/jstests/test_manage_taxonomies.jsx @@ -191,7 +191,7 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react', } }); - QUnit.test('Assert that TermComponent renders properly', + QUnit.test('Assert that edit TermComponent renders properly', function(assert) { assert.ok(TermComponent, "class object not found"); var done = assert.async(); @@ -415,7 +415,7 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react', waitForAjax(1, function() { assert.equal(component.state.label, "TestB"); assert.equal( - component.state.errorMessage, 'Unable to update term' + component.state.errorMessage, 'Unable to update term.' ); assert.equal(component.state.formatActionState, 'edit'); assert.equal(parentUpdateCount, 0); @@ -465,6 +465,137 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react', } ); + QUnit.test('Assert that delete TermComponent renders properly', + function(assert) { + assert.ok(TermComponent, "class object not found"); + var done = assert.async(); + var term = { + "id": 9, + "slug": "test", + "label": "test", + "weight": 1 + }; + var parentUpdateCount = 0; + var deleteTerm = function() { + parentUpdateCount += 1; + }; + var renderConfirmationDialog = function(options) { + options.confirmationHandler(true); + }; + + TestUtils.initMockjax({ + url: "/api/v1/repositories/repo/vocabularies/difficulty/terms/test/", + type: "DELETE" + }); + + var refreshCount = 0; + var refreshFromAPI = function() { + refreshCount++; + }; + + var afterMount = function(component) { + var deleteButton = React.addons.TestUtils. + findRenderedDOMComponentWithClass( + component, + 'revert-button' + ); + //select delete + React.addons.TestUtils.Simulate.click(deleteButton); + component.forceUpdate(function() { + assert.equal(component.state.formatActionState, 'show'); + waitForAjax(1, function() { + // term is delete in parent + assert.equal(parentUpdateCount, 1); + // listing was asked to refresh + assert.equal(refreshCount, 1); + done(); + }); + }); + }; + + React.addons.TestUtils. + renderIntoDocument( + + ); + } + ); + + QUnit.test('Assert that delete ajax call fail TermComponent' + + ' renders properly', + function(assert) { + assert.ok(TermComponent, "class object not found"); + var done = assert.async(); + var term = { + "id": 9, + "slug": "test", + "label": "test", + "weight": 1 + }; + var parentUpdateCount = 0; + var deleteTerm = function() { + parentUpdateCount += 1; + }; + var renderConfirmationDialog = function(options) { + options.confirmationHandler(true); + }; + + TestUtils.initMockjax({ + url: "/api/v1/repositories/repo/vocabularies/difficulty/terms/test/", + type: "DELETE", + status: 400 + }); + + var refreshCount = 0; + var refreshFromAPI = function() { + refreshCount++; + }; + + var afterMount = function(component) { + var deleteButton = React.addons.TestUtils. + findRenderedDOMComponentWithClass( + component, + 'revert-button' + ); + //select delete + React.addons.TestUtils.Simulate.click(deleteButton); + component.forceUpdate(function() { + assert.equal( + component.state.errorMessage, '' + ); + assert.equal(component.state.formatActionState, 'show'); + waitForAjax(1, function() { + // check state of error message + assert.equal( + component.state.errorMessage, 'Unable to delete term.' + ); + done(); + }); + }); + }; + + React.addons.TestUtils. + renderIntoDocument( + + ); + } + ); + QUnit.test('Assert that VocabularyComponent renders properly', function(assert) { assert.ok(VocabularyComponent, "class object not found"); @@ -1535,6 +1666,77 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react', } ); + QUnit.test('Assert that delete term works in TaxonomyComponent', + function(assert) { + assert.ok(TaxonomyComponent, "class object not found"); + var done = assert.async(); + var refreshCount = 0; + var refreshFromAPI = function() { + refreshCount++; + }; + + var renderConfirmationDialog = function(options) { + options.confirmationHandler(true); + }; + + var afterMount = function(component) { + assert.equal( + component.state.vocabularies.length, + 0 + ); + waitForAjax(2, function() { + assert.equal( + component.state.vocabularies.length, + 1 + ); + assert.equal( + component.state.vocabularies[0].terms.length, + 2 + ); + var updateTermUrl = "/api/v1/repositories/repo/vocabularies/" + + component.state.vocabularies[0].vocabulary.slug + "/terms/" + + component.state.vocabularies[0].terms[0].slug + "/"; + TestUtils.initMockjax({ + url: updateTermUrl, + type: "DELETE" + }); + var deleteButtons = React.addons.TestUtils. + scryRenderedDOMComponentsWithClass( + component, + 'revert-button' + ); + var deleteButton = deleteButtons[0]; + //open edit mode + React.addons.TestUtils.Simulate.click(deleteButton); + component.forceUpdate(function() { + waitForAjax(1, function () { + assert.equal(refreshCount, 1); + //assert term update + assert.equal( + component.state.vocabularies.length, + 1 + ); + assert.equal( + component.state.vocabularies[0].terms.length, + 1 + ); + done(); + }); + }); + }); + }; + React.addons.TestUtils.renderIntoDocument + ( + + ); + } + ); + QUnit.test("Test that ManageTaxonomies.loader renders into div", function(assert) { var container = document.createElement("div"); diff --git a/ui/static/ui/js/manage_taxonomies.jsx b/ui/static/ui/js/manage_taxonomies.jsx index 7c627223..fadba03a 100644 --- a/ui/static/ui/js/manage_taxonomies.jsx +++ b/ui/static/ui/js/manage_taxonomies.jsx @@ -55,7 +55,7 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'], if (formatActionState === 'show') { this.setState({ - formatActionState: 'edit', + formatActionState: 'edit' }, function() { var $editText = $(React.findDOMNode(this.refs.editText)); $editText.focus(); @@ -76,6 +76,16 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'], if (formatActionState === 'edit') { // user is in edit mode. Cancel edit if user presses cross icon. this.resetUtilityFeatures(); + } else if (formatActionState === 'show') { + var options = { + actionButtonName: "Delete", + actionButtonClass: "btn btn-danger btn-ok", + title: "Confirm Delete", + message: "Are you sure you want to delete term '" + + this.props.term.label + "'?", + confirmationHandler: this.confirmedDeleteResponse + }; + this.props.renderConfirmationDialog(options); } }, /** @@ -110,13 +120,33 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'], contentType: "application/json" }).fail(function() { thiz.setState({ - errorMessage: 'Unable to update term' + errorMessage: 'Unable to update term.' }); }).done(function(term) { thiz.resetUtilityFeatures(); thiz.props.updateTerm(thiz.props.vocabularySlug, term); thiz.props.refreshFromAPI(); }); + }, + confirmedDeleteResponse: function(success) { + var thiz = this; + if (success) { + var API_ROOT_VOCAB_URL = '/api/v1/repositories/' + this.props.repoSlug + + '/vocabularies/' + this.props.vocabularySlug + '/terms/' + + this.props.term.slug + "/"; + $.ajax({ + type: 'DELETE', + url: API_ROOT_VOCAB_URL, + contentType: "application/json" + }).fail(function() { + thiz.setState({ + errorMessage: 'Unable to delete term.' + }); + }).done(function() { + thiz.props.deleteTerm(thiz.props.vocabularySlug, thiz.props.term); + thiz.props.refreshFromAPI(); + }); + } } }); @@ -126,11 +156,13 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'], var thiz = this; var items = _.map(this.props.terms, function (term) { return ; }); @@ -256,6 +288,7 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'], var thiz = this; var items = _.map(this.props.vocabularies, function (obj) { return