From a4f48bbc17da53a5531cdbfc11c28607a53e25f7 Mon Sep 17 00:00:00 2001 From: Phoenix Eliot Date: Wed, 10 Aug 2016 14:03:17 -0700 Subject: [PATCH] Add tests for SuperModel load retrying Clear timeouts after each test --- app/models/SuperModel.coffee | 4 +- app/views/TestView.coffee | 3 ++ test/app/models/SuperModel.spec.coffee | 57 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee index ba20290f0..4637db757 100644 --- a/app/models/SuperModel.coffee +++ b/app/models/SuperModel.coffee @@ -299,7 +299,7 @@ class ModelResource extends Resource load: -> # TODO: Track progress on requests and don't retry if progress was made recently. - # Probably use _.debounce and attach event listeners to xhr objects. + # Probably use _.debounce and attach event listeners to xhr objects. # This logic is for handling failed responses for level loading. timeToWait = 5000 @@ -318,6 +318,8 @@ class ModelResource extends Resource clearTimeout(@timeoutID) clearTimeout(@timeoutID) if @timeoutID @timeoutID = setTimeout(tryLoad, timeToWait) + if application.testing + application.timeoutsToClear?.push(@timeoutID) @loadsAttempted += 1 timeToWait *= 1.5 tryLoad() diff --git a/app/views/TestView.coffee b/app/views/TestView.coffee index 14f91a545..4fa08b26a 100644 --- a/app/views/TestView.coffee +++ b/app/views/TestView.coffee @@ -101,12 +101,15 @@ module.exports = TestView = class TestView extends RootView Backbone.Mediator.init() Backbone.Mediator.setValidationEnabled false spyOn(application.tracker, 'trackEvent') + application.timeoutsToClear = [] # TODO Stubbify more things # * document.location # * firebase # * all the services that load in main.html afterEach -> + application.timeoutsToClear?.forEach (timeoutID) -> + clearTimeout(timeoutID) # TODO Clean up more things # * Events diff --git a/test/app/models/SuperModel.spec.coffee b/test/app/models/SuperModel.spec.coffee index d4d5affa3..c4c615727 100644 --- a/test/app/models/SuperModel.spec.coffee +++ b/test/app/models/SuperModel.spec.coffee @@ -1,6 +1,7 @@ SuperModel = require 'models/SuperModel' User = require 'models/User' ComponentsCollection = require 'collections/ComponentsCollection' +factories = require 'test/app/factories' describe 'SuperModel', -> @@ -57,6 +58,62 @@ describe 'SuperModel', -> request = jasmine.Ajax.requests.mostRecent() expect(request).toBeDefined() + describe 'timeout handling', -> + beforeEach -> + jasmine.clock().install() + afterEach -> + jasmine.clock().uninstall() + + it 'automatically retries stalled requests', -> + s = new SuperModel() + m = new User({_id: '12345'}) + s.loadModel(m) + timeUntilRetry = 5000 + + # Retry request 5 times + for timesTried in [1..5] + expect(s.failed).toBeFalsy() + expect(s.resources[1].loadsAttempted).toBe(timesTried) + expect(jasmine.Ajax.requests.all().length).toBe(timesTried) + jasmine.clock().tick(timeUntilRetry) + timeUntilRetry *= 1.5 + + # And then stop retrying + expect(s.resources[1].loadsAttempted).toBe(5) + expect(jasmine.Ajax.requests.all().length).toBe(5) + expect(s.failed).toBe(true) + + it 'stops retrying once the model loads', (done) -> + s = new SuperModel() + m = new User({_id: '12345'}) + s.loadModel(m) + timeUntilRetry = 5000 + # Retry request 2 times + for timesTried in [1..2] + expect(s.failed).toBeFalsy() + expect(s.resources[1].loadsAttempted).toBe(timesTried) + expect(jasmine.Ajax.requests.all().length).toBe(timesTried) + jasmine.clock().tick(timeUntilRetry) + timeUntilRetry *= 1.5 + + # Respond to the third reqest + expect(s.finished()).toBeFalsy() + expect(s.failed).toBeFalsy() + request = jasmine.Ajax.requests.mostRecent() + request.respondWith({status: 200, responseText: JSON.stringify(factories.makeUser({ _id: '12345' }).attributes)}) + + _.defer -> + expect(s.finished()).toBe(true) + expect(s.failed).toBeFalsy() + + # It shouldn't send any more requests after loading + expect(s.resources[1].loadsAttempted).toBe(3) + expect(jasmine.Ajax.requests.all().length).toBe(3) + jasmine.clock().tick(60000) + expect(s.resources[1].loadsAttempted).toBe(3) + expect(jasmine.Ajax.requests.all().length).toBe(3) + done() + describe 'events', -> it 'triggers "loaded-all" when finished', (done) -> s = new SuperModel()