-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[EOSF-594] Add example controller unit tests and component integration tests #293
Conversation
…r-preprints into feature/tests
@hmoco tests are failing, can you fix? |
bower.json
Outdated
@@ -12,7 +12,8 @@ | |||
"toastr": "^2.1.2", | |||
"hint.css": "^2.3.2", | |||
"jquery.tagsinput": "^1.3.6", | |||
"loaders.css": "^0.1.2" | |||
"loaders.css": "^0.1.2", | |||
"jquery-mockjax": "~2.2.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jquery-mockjax
sounds like something used only for testing. Could I suggest moving it to devDependencies
instead of dependencies
?
See: http://stackoverflow.com/questions/19339227/bower-and-devdependencies-vs-dependencies
…e/ember-preprints into feature/tests
…r-preprints into feature/tests
…e/ember-preprints into feature/tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's really good to see a start on testing. I can see some of the scaffolding here being very useful going forward.
That said, I do have a few suggestions on tests, eg making sure the acceptance tests focus on user facing behavior, and also possible ways to make the unit tests more concise / independent. Hopefully these will act as examples for future work.
In a few cases, it seems that your tests may have caught minor cosmetic bugs? Helping already!
package.json
Outdated
"ember-font-awesome": "2.1.1", | ||
"ember-get-config": "0.0.4", | ||
"ember-i18n": "4.3.1", | ||
"ember-link-action": "0.0.35", | ||
"ember-load-initializers": "^0.5.1", | ||
"ember-metrics": "0.6.3", | ||
"ember-osf": "0.3.0", | ||
"ember-osf": "https:/CenterForOpenScience/ember-osf.git#014fa91a442d4f2b8afe2adf0463acc1e3723ad3", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🦑 Note: this is fine for local testing, but should be changed to a real ember-osf release before this gets merged. (blocking change)
tests/acceptance/content-test.js
Outdated
|
||
moduleForAcceptance('Acceptance | content'); | ||
|
||
test('visiting /content', function(assert) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test does not appear to do anything.
Rather than comment out broken functional code, consider using skip()
in place of test()
. This will help us track problematic tests for followup. We try to avoid committing comment blocks when possible.
tests/acceptance/discover-test.js
Outdated
|
||
moduleForAcceptance('Acceptance | discover'); | ||
|
||
test('visiting /discover', function(assert) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the one hand it's nice we test these things. On the other hand, I'm fairly sure there's a way for no-value query params to simply be omitted from the URL.
Is ?provider=&subject=
a design behavior we want to test for, or a cosmetic bug?
tests/acceptance/discover-test.js
Outdated
visit('preprints/discover?provider=OSF&subject=Business'); | ||
|
||
andThen(() => { | ||
let controller = container.lookup('controller:discover'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good quote from the docs:
Acceptance tests are used to test user interaction and application flow. The tests interact with the application in the same ways that a user would, by doing things like filling out form fields and clicking buttons...
In general, it seems like the acceptance test should focus on what the result looks like to the user, without knowing how the internals (the controller) are implemented. Perhaps the things that check controller behavior would be better suited to, say, a unit test?
To make the difference actionable for this PR- one thing we could do is to check whether the desired checkboxes are correctly selected. That's a user-facing behavior related to the query params, and a good candidate for an acceptance test.
} | ||
this.application = startApp(); | ||
FakeServer.start(); | ||
manualSetup(this.application.__container__); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General comment for this PR: is this necessary?
From docs:
By default, you only need to call manualSetup(this.container) in unit/component tests
See also the factory guy setup for comparison in case it sparks some ideas:
https:/danielspaniel/ember-data-factory-guy/blob/master/tests/helpers/module-for-acceptance.js
year: '{{year}}', | ||
copyright_holders: ['{{copyrightHolders}}'] | ||
}); | ||
ctrl.notifyPropertyChange('model.license'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See questions above about computeds/ use of notifyPropertyChange
.
Also, if we are intending to test multiple different scenarios, I generally recommend doing each in a separate test
to ensure that the behaviors are isolated. It does not appear that the three scenarios are interdependent, though I could be missing something.
let ctrl = this.subject(); | ||
let node = FactoryGuy.make('node'); | ||
ctrl.set('node', node); | ||
Ember.run(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
In general, whenever you put code in a run loop, you want to make sure it actually ran before the test ended. One very easy safeguard is to use
assert.expect(99)
at the very top of the test (outside the run loop) to tell it how many assertions you thought would run. (this has saved me a few times when testing async behavior) -
Does this need to be in
Ember.run
? If not, item 1 might not be necessary. ;) -
Realistically, there are three separate scenarios that could each be a separate
test()
. If we shorten this to provide each description when the node is first created, I think we can do away with the.run
and thenotifyPropertyChange
altogether.
Eg: let user = make('node', {description: 's'.repeat(350)});
let description = 'string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string str'; | ||
let notExpanded = description.slice(0, 350); | ||
node.set('description', description); | ||
ctrl.notifyPropertyChange('description'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned elsewhere, not sure this part is needed?
Also, each scenario should be its own test to ensure isolation.
//Test less than 350 doesn't use description (uses node.description) | ||
|
||
ctrl.set('expandedAbstract', true); | ||
// expandedAbstract logic has been moved to the template, making the expanded tests unnescessary here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per this note: does this mean that any code after the last assertion can be removed?
manualSetup(this.application.__container__); | ||
const url = config.OSF.apiUrl; | ||
const provider = FactoryGuy.build('preprint-provider'); | ||
stubRequest('get', url + '/v2/users/me', (request) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks helpful!
I ran the tests in chrome with the network inspector open, and noticed that the page still sends a request to google analytics every time tests run. This may indicate one more thing that needs stubbing. Thoughts?
…r-preprints into feature/tests
…e/ember-preprints into feature/tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start on improving test coverage. My only reservations are to make sure that even minor formatting changes are mentioned in Side Effects and that I recommend adding messages when there is more than one assertion in a test to make it clear why a test is failing. In general, I think messages are useful, even when there is only one assertion, and even if the assertion is somewhat obvious. I always think it's better to give explicit feedback when it comes to test failures.
app/controllers/content/index.js
Outdated
@@ -137,7 +137,7 @@ export default Ember.Controller.extend(Analytics, { | |||
let text = this.get('model.license.text'); | |||
if (text) { | |||
text = text.replace(/({{year}})/g, this.get('model.licenseRecord').year || ''); | |||
text = text.replace(/({{copyrightHolders}})/g, this.get('model.licenseRecord').copyright_holders ? this.get('model.licenseRecord').copyright_holders.join(',') : false || ''); | |||
text = text.replace(/({{copyrightHolders}})/g, this.get('model.licenseRecord').copyright_holders ? this.get('model.licenseRecord').copyright_holders.join(', ') : false || ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though this change is minor, it'd be good to mention it in Side Effects just to bring it to attention of QA and others.
contributor = Ember.merge(contributor, contributorModel.serialize().data.attributes); | ||
this.set('contributor', contributor); | ||
this.render(hbs`{{author-link contributor=contributor}}`); | ||
assert.ok(!this.$('a').length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
this.set('contributor', contributor); | ||
this.render(hbs`{{author-link contributor=contributor}}`); | ||
assert.ok(!this.$('a').length); | ||
assert.equal(this.$().text().trim(), contributorModel.get('users.fullName')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
this.set('contributor', contributor); | ||
|
||
this.render(hbs`{{author-link contributor=contributor}}`); | ||
assert.ok(this.$('a').length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
|
||
this.render(hbs`{{author-link contributor=contributor}}`); | ||
assert.ok(this.$('a').length); | ||
assert.equal(this.$().text().trim(), contributorModel.get('users.fullName')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
assert.ok(ctrl.get('useShortenedDescription')); | ||
|
||
node.set('description', 'string'.repeat(100).slice(0, 350)); | ||
assert.ok(!ctrl.get('useShortenedDescription')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
assert.ok(!ctrl.get('useShortenedDescription')); | ||
|
||
node.set('description', 'string'.repeat(100).slice(0, 349)); | ||
assert.ok(!ctrl.get('useShortenedDescription')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
let description = 'string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string str'; | ||
let notExpanded = description.slice(0, 350); | ||
node.set('description', description); | ||
assert.equal(ctrl.get('description'), notExpanded.trim()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
description = 'string stringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstringstring'; | ||
notExpanded = 'string '; | ||
node.set('description', description); | ||
assert.equal(ctrl.get('description'), notExpanded.trim()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add message?
app/controllers/submit.js
Outdated
@@ -304,7 +304,7 @@ export default Ember.Controller.extend(Analytics, BasicsValidations, NodeActions | |||
let license = this.get('model.license'); | |||
return { | |||
year: record ? record.year : null, | |||
copyrightHolders: record && record.copyright_holders ? record.copyright_holders.join(',') : null, | |||
copyrightHolders: record && record.copyright_holders ? record.copyright_holders.join(', ') : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SAA about mentioning this in Side Effects.
Probably should revert changes in controllers, as I've made major updates in #319 |
Indeed. It looks like #319 should probably be merged first? There will likely be several merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add a submit controller test for multiple copyright holders.
@@ -684,7 +684,7 @@ export default Ember.Controller.extend(Analytics, BasicsValidations, NodeActions | |||
this.set('basicsLicense', { | |||
licenseType: license || this.get('availableLicenses').toArray()[0], | |||
year: this.get('model.licenseRecord') ? this.get('model.licenseRecord').year : date.getUTCFullYear().toString(), | |||
copyrightHolders: this.get('model.licenseRecord') ? this.get('model.licenseRecord').copyright_holders.join(',') : '' | |||
copyrightHolders: this.get('model.licenseRecord') ? this.get('model.licenseRecord').copyright_holders.join(', ') : '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add a test for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend using the wait() test helper instead to test asynchronous parts of the discardBasics action.
…) test helper instead Upgrading to ember-cli-qunit 3 was required due to bug in v2 that prevents use of asynchronous wait helpers.
@brianjgeiger, can't get this to fail locally, can't get it to pass here. Any ideas? |
merge develop, then it will fail locally |
…r-preprints into feature/tests
Also, I wanted to reference ember-cli/ember-cli-qunit#162, which discusses the issue using wait helpers with qunitjs < 2.3.1 and qunitjs/qunit#1148, which was the fix to qunitjs that allows assertions after assert.async(). Switching to ember-cli-qunit 3 was necessary because ember-cli-qunit 2 depends on qunitjs 1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved by @jamescdavis
This PR has been diminished in scope due to problems found with acceptance testing. Ticket previously tracking this PR is https://openscience.atlassian.net/browse/EOSF-510
Ticket
https://openscience.atlassian.net/browse/EOSF-594
Purpose
Improve test coverage, with integration and controller tests, to allow simpler future tests writing.
Changes
Use of ember-osf factories