Skip to content
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

test: Fix/update the ajax tests to be a little more correct #6002

Merged
merged 1 commit into from
Feb 8, 2021

Conversation

benlesh
Copy link
Member

@benlesh benlesh commented Feb 8, 2021

Moved the spec updates to a different PR than #6001 so they can be reviewed separately. That way it's perhaps easier to tell they're doing the same thing.

@@ -298,39 +294,41 @@ describe('ajax', () => {

MockXMLHttpRequest.mostRecent.respondWith({
status: 200,
contentType: 'application/json',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contentType does nothing for this test. Here we assume that the browser is working as expected, and we deal with the responseType, which the browser sets for us. Since all of that process is mocked, switching to using responseType only in our tests.

let error: any;
const obj: AjaxConfig = {
url: '/flibbertyJibbet',
responseType: 'json',
method: '',
};

// No `response` property on the object (for older IE).
MockXMLHttpRequest.noResponseProp = true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new feature to the Mock that will strip the response property from the xhr to simulate an older browser that lacks that feature.

ajax(obj).subscribe(
() => {
throw 'should not next';
throw new Error('should not next');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making sure that errors thrown are recognized and processed properly by the test framework.

@@ -558,26 +555,17 @@ describe('ajax', () => {
async: false,
};

ajax(obj).subscribe(
(x: any) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing in here mattered, accept the check of x.xhr.async, but it's unremarkable that it's in the subscribe next callback. So I've cleaned this a bit to make the test simpler.

expect(request.url).to.equal('/flibbertyJibbet');
expect(mockXHR.url).to.equal('/flibbertyJibbet');
// Open was called with async `false`.
expect(mockXHR.async).to.be.false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the most important part of this test. This is only set when the XHR's open method is called, and it defaults to true.

@@ -728,7 +716,6 @@ describe('ajax', () => {
});

it('should succeed on 204 No Content', () => {
const expected: null = null;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null didn't make any sense here. a real XHR would never have null in the responseText, or the response.

contentType: 'application/json',
responseText: expected,
responseType: '',
responseText: '',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is more akin to what you'd see in a real call like this.

let result: AjaxResponse<any>;
let complete = false;

ajax.post('/flibbertyJibbet', expected).subscribe(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no idea why I chose to post a body of null here, seems weird. But this whole test was really just to check that 204 status passed okay.

responseText: JSON.stringify({}),
},
3
{ uploadProgressTimes: 3 }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a change to configuration for these.

/**
* Set to `true` to test IE code paths.
*/
static noResponseProp = false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is that new property that is used to simulate older browsers that would lack a response property on their XHR.

@@ -1140,19 +1133,23 @@ class MockXMLHttpRequest {
}

static clearRequest(): void {
MockXMLHttpRequest.noResponseProp = false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making sure we reset it here.

/**
* Used to test if `open` was called with `async` true or false.
*/
public async: boolean = true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this public so we can test it. (self nit: I should have removed the public and just let it be public, but we should probably use a lint rule for that)

@@ -1173,6 +1170,9 @@ class MockXMLHttpRequest {
constructor() {
MockXMLHttpRequest.recentRequest = this;
MockXMLHttpRequest.requests.push(this);
if (MockXMLHttpRequest.noResponseProp) {
delete this['response'];
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above here is part of the magic for removing the response property from the XHR to simulate older browsers.

total?: number;
loaded?: number;
},
config?: { uploadProgressTimes?: number; downloadProgressTimes?: number }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New configuration options for triggering the upload and download progress events (including loadstart for each)

this.status = response.status || 200;
this.responseText = response.responseText;
const responseType = response.responseType !== undefined ? response.responseType : this.responseType;
if (!('response' in response)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could have left this I suppose, since I'm removing the property, but I think this in check was kind of confusing, so I opted to just let this switch process. And remove the response property again after.

if (!('response' in response)) {
switch (responseType) {
case 'json':
this.jsonResponseValue(response);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this got inlined.

delete this['response'];
}

this.triggerEvent('load', { type: 'load', total: response.total ?? 0, loaded: response.loaded ?? 0 });
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a duck-typed load event here.

@benlesh benlesh merged commit 412d1fd into ReactiveX:master Feb 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants