diff --git a/app/adapters/search-index.js b/app/adapters/search-index.js index ea0a552..9fe3ca7 100644 --- a/app/adapters/search-index.js +++ b/app/adapters/search-index.js @@ -10,7 +10,6 @@ var SearchIndexAdapter = DS.RESTAdapter.extend({ let url = this.buildURL(type.modelName, null, null, 'query', query); let promise = this.ajax(url, 'GET').then(function(indexes) { - indexes.forEach(function(index) { index.id = `${query.clusterId}/${index.name}`; }); @@ -23,3 +22,4 @@ var SearchIndexAdapter = DS.RESTAdapter.extend({ }); export default SearchIndexAdapter; + diff --git a/app/components/code-highlighter.js b/app/components/code-highlighter.js new file mode 100644 index 0000000..37a6aab --- /dev/null +++ b/app/components/code-highlighter.js @@ -0,0 +1,14 @@ +import Ember from 'ember'; +/* global hljs */ + +export default Ember.Component.extend({ + tagName: 'pre', + + classNames: ['code-highlighter'], + + didRender() { + let codeBlock = this.$().find('code')[0]; + + hljs.highlightBlock(codeBlock); + } +}); diff --git a/app/index.html b/app/index.html index 69edb1a..870fcd7 100644 --- a/app/index.html +++ b/app/index.html @@ -8,6 +8,7 @@ {{content-for 'head'}} + {{content-for 'head-footer'}} diff --git a/app/pods/cluster/model.js b/app/pods/cluster/model.js index e686283..1c0ecbf 100644 --- a/app/pods/cluster/model.js +++ b/app/pods/cluster/model.js @@ -32,6 +32,13 @@ var Cluster = DS.Model.extend({ */ searchIndexes: DS.hasMany('search-index', { async: true }), + /** + * Search schemas created on the cluster + * @property searchSchemas + * @type Array + */ + searchSchemas: DS.hasMany('search-schema', { async: true }), + /** * Is this cluster in Dev Mode? Set in the Explorer config file. * Dev mode allows expensive operations like list keys, delete bucket, etc. diff --git a/app/pods/cluster/template.hbs b/app/pods/cluster/template.hbs index 02fbf01..9b1053b 100644 --- a/app/pods/cluster/template.hbs +++ b/app/pods/cluster/template.hbs @@ -57,11 +57,14 @@ {{/if}} {{/dashboard-module}} - {{#dashboard-module label='Search Indexes'}} + {{#dashboard-module label='Search Overview'}} + {{#link-to 'search-schema.create' model.id class='btn btn-small btn-primary'}} + + Create new search schema + {{/link-to}} + {{#if model.searchIndexes}} - {{search-indexes - indexes=model.searchIndexes - clusterProxyUrl=model.proxyUrl}} + {{search-indexes indexes=model.searchIndexes}} {{else}}

No search indexes found

{{/if}} diff --git a/app/pods/search-index/model.js b/app/pods/search-index/model.js index 69a7fe3..973c5ef 100644 --- a/app/pods/search-index/model.js +++ b/app/pods/search-index/model.js @@ -2,13 +2,22 @@ import DS from 'ember-data'; var SearchIndex = DS.Model.extend({ /** - * Riak cluster in the search index wascreated on + * Riak cluster the search index was created on * * @property cluster * @type {DS.Model} Cluster * @writeOnce */ - cluster: DS.belongsTo('cluster'), + cluster: DS.belongsTo('cluster', { async: true }), + + /** + * Schema the search index is using + * + * @property schema + * @type {DS.Model} Search Schema + * @writeOnce + */ + schema: DS.belongsTo('search-schema', { async: true }), /** * Returns the search index name/id @@ -25,11 +34,12 @@ var SearchIndex = DS.Model.extend({ nVal: DS.attr('number', {defaultValue: 3}), /** - * Name of the schema the index is using - * @property schema - * @type String + * Holds the value of the schema name that index is using. + * Temporary hack until basho-labs/riak_explorer#89 is completed + * @property nVal + * @type Integer */ - schema: DS.attr('string'), + schemaRef: DS.attr('string'), /** * Ember.Array of bucket types on the current cluster using the index @@ -40,19 +50,7 @@ var SearchIndex = DS.Model.extend({ let bucketTypes = this.get('cluster').get('bucketTypes'); return bucketTypes.filterBy('index.name', this.get('name')); - }.property('cluster.bucketTypes'), - - /** - * Returns a formatted schema url - * @property schemaUrl - * @type String - */ - schemaUrl: function() { - let proxyURL = this.get('cluster').get('proxyUrl'); - let schema = this.get('schema'); - - return `${proxyURL}/search/schema/${schema}`; - }.property('schema', 'cluster.proxyUrl') + }.property('cluster.bucketTypes') }); export default SearchIndex; diff --git a/app/pods/search-index/template.hbs b/app/pods/search-index/template.hbs index 56bda36..89c0eff 100644 --- a/app/pods/search-index/template.hbs +++ b/app/pods/search-index/template.hbs @@ -22,7 +22,9 @@ Schema - {{model.schema}} + {{#link-to 'search-schema' model.cluster.id model.schema.name class='btn btn-small btn-primary'}} + {{model.schema.name}} + {{/link-to}} diff --git a/app/pods/search-schema/create/controller.js b/app/pods/search-schema/create/controller.js new file mode 100644 index 0000000..436c2bd --- /dev/null +++ b/app/pods/search-schema/create/controller.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + schemaName: '', + schemaContent: '' +}); diff --git a/app/pods/search-schema/create/route.js b/app/pods/search-schema/create/route.js new file mode 100644 index 0000000..d98db72 --- /dev/null +++ b/app/pods/search-schema/create/route.js @@ -0,0 +1,49 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + model(params) { + return this.explorer.getCluster(params.clusterId, this.store); + }, + + actions: { + createSchema: function(clusterId, schemaName, schemaContent) { + let self = this; + let xmlDoc = null; + let url = `/riak/clusters/${clusterId}/search/schema/${schemaName}`; + + try { + xmlDoc = Ember.$.parseXML(schemaContent); + } catch(error) { + // TODO: Put in proper error messaging + alert('Invalid XML. Please check and make sure schema is valid xml.'); + return; + } + + if (!Ember.$(xmlDoc).find('schema').attr('name')) { + // TODO: Put in proper error messaging + alert('Solr requires that the schema tag has a name attribute. Please update your xml.'); + return; + } + + if (!Ember.$(xmlDoc).find('schema').attr('version')) { + // TODO: Put in proper error messaging + alert('Solr requires that the schema tag has a version attribute. Please update your xml.'); + return; + } + + return Ember.$.ajax({ + type: 'PUT', + url: url, + contentType: 'application/xml', + processData: false, + data: xmlDoc + }).then(function(data) { + self.transitionTo('search-schema', clusterId, schemaName); + }, function(error) { + // TODO: Put in proper error messaging + alert('Something went wrong, schema was not saved.'); + }); + } + } + +}); diff --git a/app/pods/search-schema/create/template.hbs b/app/pods/search-schema/create/template.hbs new file mode 100644 index 0000000..c5c033f --- /dev/null +++ b/app/pods/search-schema/create/template.hbs @@ -0,0 +1,34 @@ +
+ {{breadcrumb-component + clusterId=model.clusterId + pageTitle='create schema' + }} + {{view-label + pre-label='Create Schema'}} +
+ +{{#dashboard-module}} +
+ + + Create Schema + + + {{#link-to 'cluster' model.clusterId class='cancel schema-action' }} + + Cancel + {{/link-to}} +
+ +
+
+ + {{input value=schemaName class='form-control'}} +
+ +
+ + {{textarea value=schemaContent rows=10 class='form-control'}} +
+
+{{/dashboard-module}} diff --git a/app/pods/search-schema/edit/route.js b/app/pods/search-schema/edit/route.js new file mode 100644 index 0000000..ea8c1ce --- /dev/null +++ b/app/pods/search-schema/edit/route.js @@ -0,0 +1,55 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + model(params) { + return this.explorer.getCluster(params.clusterId, this.store) + .then(function(cluster){ + return cluster.get('searchSchemas').findBy('name', params.searchSchemaId); + }); + }, + + afterModel(model, transition) { + if (!model.get('content')) { + return Ember.$.ajax({ + type: 'GET', + url: model.get('url'), + dataType: 'xml' + }).then(function(data) { + let xmlString = (new XMLSerializer()).serializeToString(data); + model.set('content', xmlString); + }); + } + }, + + actions: { + updateSchema: function(schema) { + let xmlString = schema.get('content'); + let self = this; + let xmlDoc = null; + let clusterId = schema.get('cluster').get('id'); + let schemaId = schema.get('name'); + + try { + xmlDoc = Ember.$.parseXML(xmlString); + } catch(error) { + // TODO: Put in proper error messaging + alert('Invalid XML. Please check and make sure schema is valid xml.'); + return; + } + + return Ember.$.ajax({ + type: 'PUT', + url: schema.get('url'), + contentType: 'application/xml', + processData: false, + data: xmlDoc + }).then(function(data) { + self.transitionTo('search-schema', clusterId, schemaId); + }, function(error) { + // TODO: Put in proper error messaging + alert('Something went wrong, schema was not saved.'); + self.transitionTo('search-schema', clusterId, schemaId); + }); + } + } +}); diff --git a/app/pods/search-schema/edit/template.hbs b/app/pods/search-schema/edit/template.hbs new file mode 100644 index 0000000..95446bc --- /dev/null +++ b/app/pods/search-schema/edit/template.hbs @@ -0,0 +1,31 @@ +
+ {{breadcrumb-component + clusterId=model.cluster.id + pageTitle=model.name + }} + {{view-label + pre-label='Search Schema' + label=model.name}} +
+ +{{#dashboard-module}} +
+ + + Update Schema + + + {{#link-to 'search-schema' model.cluster.id model.name class='cancel schema-action' }} + + Cancel + {{/link-to}} +
+ +
+        
+            {{content-editable
+            value=model.content
+            type="html"}}
+        
+    
+{{/dashboard-module}} diff --git a/app/pods/search-schema/model.js b/app/pods/search-schema/model.js new file mode 100644 index 0000000..26622b1 --- /dev/null +++ b/app/pods/search-schema/model.js @@ -0,0 +1,28 @@ +import DS from 'ember-data'; + +export default DS.Model.extend({ + /** + * Riak cluster the search schema was created on + * + * @property cluster + * @type {DS.Model} Cluster + * @writeOnce + */ + cluster: DS.belongsTo('cluster', { async: true }), + + name: DS.attr('string'), + + content: DS.attr(), + + /** + * Returns a formatted schema url + * @method url + * @returns String + */ + url: function() { + let proxyURL = this.get('cluster').get('proxyUrl'); + let name = this.get('name'); + + return `${proxyURL}/search/schema/${name}`; + }.property('name', 'cluster.proxyUrl') +}); diff --git a/app/pods/search-schema/route.js b/app/pods/search-schema/route.js new file mode 100644 index 0000000..8863598 --- /dev/null +++ b/app/pods/search-schema/route.js @@ -0,0 +1,30 @@ +import Ember from 'ember'; +import $ from 'jquery'; + +export default Ember.Route.extend({ + model(params) { + let self = this; + + return this.explorer.getCluster(params.clusterId, this.store) + .then(function(cluster){ + let schema = cluster.get('searchSchemas').findBy('name', params.searchSchemaId); + + if (!schema) { + schema = self.explorer.createSchema(params.searchSchemaId, cluster, self.store); + } + + return schema; + }); + }, + + afterModel(model, transition) { + return Ember.$.ajax({ + type: 'GET', + url: model.get('url'), + dataType: 'xml' + }).then(function(data) { + let xmlString = (new XMLSerializer()).serializeToString(data); + model.set('content', xmlString); + }); + } +}); diff --git a/app/pods/search-schema/template.hbs b/app/pods/search-schema/template.hbs new file mode 100644 index 0000000..f64b380 --- /dev/null +++ b/app/pods/search-schema/template.hbs @@ -0,0 +1,25 @@ +
+ {{breadcrumb-component + clusterId=model.cluster.id + pageTitle=model.name + }} + {{view-label + pre-label='Search Schema' + label=model.name}} +
+ +{{#dashboard-module}} +
+ {{#link-to 'search-schema.edit' model.cluster.id model.name class='edit schema-action' }} + + Edit Schema + {{/link-to}} + + + View Raw + +
+ {{#code-highlighter language-type='XML'}} + {{model.content}} + {{/code-highlighter}} +{{/dashboard-module}} diff --git a/app/router.js b/app/router.js index 75decf5..c1ff7f8 100644 --- a/app/router.js +++ b/app/router.js @@ -30,4 +30,8 @@ export default Router.map(function() { this.route('service-not-found'); }); this.route('search-index', { path: '/cluster/:clusterId/index/:searchIndexId' }); + + this.route('search-schema', { path: '/cluster/:clusterId/schema/:searchSchemaId' }); + this.route('search-schema.edit', { path: '/cluster/:clusterId/schema/:searchSchemaId/edit' }); + this.route('search-schema.create', { path: '/cluster/:clusterId/schema/create' }); }); diff --git a/app/routes/application.js b/app/routes/application.js index f1de7b3..5f0431f 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -5,7 +5,7 @@ export default Ember.Route.extend({ error: function(error) { // An error has occurred that wasn't handled by any route. console.log('Unknown error: %O', error); - this.transitionTo('errors.unknown'); + this.transitionTo('error.unknown'); } }, diff --git a/app/serializers/search-index.js b/app/serializers/search-index.js index 09fe057..5f2358d 100644 --- a/app/serializers/search-index.js +++ b/app/serializers/search-index.js @@ -7,5 +7,13 @@ export default ApplicationSerializer.extend({ }; return this._super(store, primaryModelClass, newPayload, id, requestType); + }, + + // TODO: Remove once basho-labs/riak_explorer#89 is completed + normalize(modelClass, resourceHash, prop) { + resourceHash.schema_ref = resourceHash.schema; + delete resourceHash.schema; + + return this._super(modelClass, resourceHash, prop); } }); diff --git a/app/services/explorer.js b/app/services/explorer.js index d753aa8..d527277 100644 --- a/app/services/explorer.js +++ b/app/services/explorer.js @@ -88,15 +88,15 @@ export default Ember.Service.extend({ }, /** - * Refreshes a key list cache or bucket list cache on the Explorer API side. - * Usually invoked when the user presses the 'Refresh List' button on the UI. - * @see bucketCacheRefresh - * @see keyCacheRefresh - * - * @method cacheRefresh - * @param {String} url - * @return Ember.RSVP.Promise - */ + * Refreshes a key list cache or bucket list cache on the Explorer API side. + * Usually invoked when the user presses the 'Refresh List' button on the UI. + * @see bucketCacheRefresh + * @see keyCacheRefresh + * + * @method cacheRefresh + * @param {String} url + * @return Ember.RSVP.Promise + */ cacheRefresh(url) { return new Ember.RSVP.Promise(function(resolve, reject) { Ember.$.ajax({ @@ -197,7 +197,7 @@ export default Ember.Service.extend({ // This `field` becomes the `parentMap` for the nested fields. // `rootMap` stays the same let mapFields = this.collectMapFields(rootMap, field, - payload[fieldName], store); + payload[fieldName], store); field.value = mapFields; contents.maps[fieldName] = field; } @@ -293,6 +293,30 @@ export default Ember.Service.extend({ }); }, + /** + * Creates a Schema instance if it does not exist, + * and the returns instance. + * + * @method createSchema + * @param name {String} + * @param cluster {Cluster} + * @param store {DS.Store} + * @return {Schema} + */ + createSchema(name, cluster, store) { + let schema = cluster.get('searchSchemas').findBy('name', name); + + if (!schema) { + schema = store.createRecord('search-schema', { + id: `${cluster.get('id')}/${name}`, + cluster: cluster, + name: name + }); + } + + return schema; + }, + /** * Parses and returns the contents/value of a Riak Object, depending on * whether it's a CRDT or a plain object. @@ -791,11 +815,11 @@ export default Ember.Service.extend({ */ getBucketTypeWithBucketList(bucketType, cluster, store, start, row) { return this - .getBucketList(cluster, bucketType, store, start, row) - .then(function(bucketList) { - bucketType.set('bucketList', bucketList); - return bucketType; - }); + .getBucketList(cluster, bucketType, store, start, row) + .then(function(bucketList) { + bucketType.set('bucketList', bucketList); + return bucketType; + }); }, /** @@ -815,7 +839,7 @@ export default Ember.Service.extend({ // (via a bookmark and not from a link), bucket types are likely // to be not loaded yet. Load them. return store.query('bucket-type', - {clusterId: cluster.get('clusterId')}) + {clusterId: cluster.get('clusterId')}) .then(function(bucketTypes) { cluster.set('bucketTypes', bucketTypes); return bucketTypes; @@ -866,6 +890,14 @@ export default Ember.Service.extend({ .then(function(PromiseArray) { let cluster = PromiseArray[0].value; + // Create search-schemas from index references + // and set the schema/index association + cluster.get('searchIndexes').forEach(function(index) { + let schema = self.createSchema(index.get('schemaRef'), cluster, store); + + index.set('schema', schema); + }); + return cluster; }); }, @@ -1175,20 +1207,20 @@ export default Ember.Service.extend({ // if the header value has the string ": " in it. var index = headerLine.indexOf(': '); if (index > 0) { - var key = headerLine.substring(0, index).toLowerCase(); - var val = headerLine.substring(index + 2); - var header = { - key: key, - value: val - }; - - if(key.startsWith('x-riak-meta')) { - custom.push(header); - } else if(key.startsWith('x-riak-index')) { - indexes.push(header); - } else { - other_headers[key] = val; - } + var key = headerLine.substring(0, index).toLowerCase(); + var val = headerLine.substring(index + 2); + var header = { + key: key, + value: val + }; + + if(key.startsWith('x-riak-meta')) { + custom.push(header); + } else if(key.startsWith('x-riak-index')) { + indexes.push(header); + } else { + other_headers[key] = val; + } } } return { diff --git a/app/styles/app.scss b/app/styles/app.scss index ec26969..52e518d 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -24,6 +24,9 @@ @import "components/button-list"; @import "components/cluster-resource-link"; @import "components/pagination-component"; +@import "components/schema-actions"; +@import "components/code-highlter"; +@import "components/content-editable"; // View specific styling @import "views/object-counter-container"; diff --git a/app/styles/components/_code-highlter.scss b/app/styles/components/_code-highlter.scss new file mode 100644 index 0000000..16da0c1 --- /dev/null +++ b/app/styles/components/_code-highlter.scss @@ -0,0 +1,10 @@ +.code-highlighter { + padding: 0; + margin: 0; + border: none; + background: none; + + code { + border-radius: 4px; + } +} diff --git a/app/styles/components/_content-editable.scss b/app/styles/components/_content-editable.scss new file mode 100644 index 0000000..d8fbde3 --- /dev/null +++ b/app/styles/components/_content-editable.scss @@ -0,0 +1,18 @@ +// Don't focus when inside of a code block +code { + .ember-content-editable { + margin-top: -50px; // Not sure why this space is being added to the component + min-height: 100px; + + &:focus { + outline: none; + } + } +} + +pre.editable { + background: #FFF; + border-color: #000; + border-radius: 0px; +} + diff --git a/app/styles/components/_schema-actions.scss b/app/styles/components/_schema-actions.scss new file mode 100644 index 0000000..21fc856 --- /dev/null +++ b/app/styles/components/_schema-actions.scss @@ -0,0 +1,30 @@ +.schema-actions { + text-align: right; + margin-bottom: 10px; + + .schema-action { + @extend .btn; + @extend .btn-sm; + margin-left: 10px; + } + + .edit { + @extend .btn-primary; + } + + .cancel { + @extend .btn-danger; + } + + .update { + @extend .btn-primary; + } + + .create { + @extend .btn-primary; + } + + .raw { + @extend .btn-primary; + } +} diff --git a/app/templates/components/code-highlighter.hbs b/app/templates/components/code-highlighter.hbs new file mode 100644 index 0000000..803f55c --- /dev/null +++ b/app/templates/components/code-highlighter.hbs @@ -0,0 +1,4 @@ + + {{yield}} + + diff --git a/app/templates/components/search-indexes.hbs b/app/templates/components/search-indexes.hbs index 9d7eb45..d970830 100644 --- a/app/templates/components/search-indexes.hbs +++ b/app/templates/components/search-indexes.hbs @@ -10,7 +10,11 @@ {{#each indexes as |index|}} {{link.link-index searchIndex=index}} - {{index.schema}} + + {{#link-to 'search-schema' index.cluster.id index.schema.name class='btn btn-small btn-primary'}} + {{index.schema.name}} + {{/link-to}} + {{index.nVal}} {{else}} diff --git a/bower.json b/bower.json index 0798b1d..d9b6667 100644 --- a/bower.json +++ b/bower.json @@ -12,6 +12,7 @@ "jquery": "^1.11.1", "loader.js": "ember-cli/loader.js#3.2.0", "bootstrap-sass": "~3.3.5", - "qunit": "~1.17.1" + "qunit": "~1.17.1", + "highlightjs": "~9.0.0" } } diff --git a/ember-cli-build.js b/ember-cli-build.js index a0c0b84..9582b7a 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -18,6 +18,8 @@ module.exports = function(defaults) { // modules that you would like to import into your application // please specify an object with the list of modules as keys // along with the exports of each module as its value. + app.import('bower_components/highlightjs/highlight.pack.js'); + app.import('bower_components/highlightjs/styles/default.css'); return app.toTree(); }; diff --git a/package.json b/package.json index ac4c4ef..ca36de3 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,8 @@ }, "dependencies": { "ember-cli-sass": "^5.1.0", - "ember-idx-tabs": "^0.1.4" + "ember-content-editable": "0.7.0", + "ember-idx-tabs": "^0.1.4", + "highlightjs": "^8.7.0" } } diff --git a/tests/integration/components/code-highlighter-test.js b/tests/integration/components/code-highlighter-test.js new file mode 100644 index 0000000..d82936d --- /dev/null +++ b/tests/integration/components/code-highlighter-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('code-highlighter', 'Integration | Component | code highlighter', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{code-highlighter}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#code-highlighter}} + template block text + {{/code-highlighter}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/tests/unit/models/cluster-test.js b/tests/unit/models/cluster-test.js index ae8c57f..5344832 100644 --- a/tests/unit/models/cluster-test.js +++ b/tests/unit/models/cluster-test.js @@ -2,7 +2,7 @@ import { moduleForModel, test, pending } from 'ember-qunit'; import Ember from 'ember'; moduleForModel('cluster', 'Unit | Model | cluster', { - needs: ['model:bucketType', 'model:riakNode', 'model:searchIndex'] + needs: ['model:bucketType', 'model:riakNode', 'model:searchIndex', 'model:searchSchema'] }); test('it exists', function(assert) { @@ -37,6 +37,14 @@ test('searchIndexes relationship', function(assert) { assert.equal(relationship.kind, 'hasMany'); }); +test('searchSchemas relationship', function(assert) { + let klass = this.subject({}).constructor; + let relationship = Ember.get(klass, 'relationshipsByName').get('searchSchemas'); + + assert.equal(relationship.key, 'searchSchemas'); + assert.equal(relationship.kind, 'hasMany'); +}); + pending('getting active bucket types', function() {}); pending('getting inactive bucket types', function() {}); diff --git a/tests/unit/models/search-index-test.js b/tests/unit/models/search-index-test.js index e1e5f98..05d0854 100644 --- a/tests/unit/models/search-index-test.js +++ b/tests/unit/models/search-index-test.js @@ -2,7 +2,7 @@ import { moduleForModel, test } from 'ember-qunit'; import Ember from 'ember'; moduleForModel('search-index', 'Unit | Model | search index', { - needs: ['model:cluster'] + needs: ['model:cluster', 'model:searchSchema'] }); test('it exists', function(assert) { @@ -21,3 +21,12 @@ test('cluster relationship', function (assert) { assert.equal(relationship.kind, 'belongsTo'); }); + +test('schema relationship', function (assert) { + let klass = this.subject({}).constructor; + let relationship = Ember.get(klass, 'relationshipsByName').get('schema'); + + assert.equal(relationship.key, 'schema'); + + assert.equal(relationship.kind, 'belongsTo'); +}); diff --git a/tests/unit/models/search-schema-test.js b/tests/unit/models/search-schema-test.js new file mode 100644 index 0000000..466c271 --- /dev/null +++ b/tests/unit/models/search-schema-test.js @@ -0,0 +1,24 @@ +import { moduleForModel, test } from 'ember-qunit'; +import Ember from 'ember'; + +moduleForModel('search-schema', 'Unit | Model | search schema', { + // Specify the other units that are required for this test. + needs: ['model:cluster'] +}); + +test('it exists', function(assert) { + let model = this.subject(); + let store = this.store(); + + assert.ok(!!model); + assert.ok(!!store); +}); + +test('cluster relationship', function (assert) { + let klass = this.subject({}).constructor; + let relationship = Ember.get(klass, 'relationshipsByName').get('cluster'); + + assert.equal(relationship.key, 'cluster'); + + assert.equal(relationship.kind, 'belongsTo'); +}); diff --git a/tests/unit/serializers/search-index-test.js b/tests/unit/serializers/search-index-test.js index 8850c4a..58730e3 100644 --- a/tests/unit/serializers/search-index-test.js +++ b/tests/unit/serializers/search-index-test.js @@ -2,7 +2,7 @@ import { moduleForModel, test } from 'ember-qunit'; moduleForModel('search-index', 'Unit | Serializer | search index', { // Specify the other units that are required for this test. - needs: ['serializer:search-index'] + needs: ['serializer:search-index', 'model:search-schema'] }); // Replace this with your real tests.