spec_app/spec/javascripts/up/form_spec.js.coffee in upjs-rails-0.17.0 vs spec_app/spec/javascripts/up/form_spec.js.coffee in upjs-rails-0.18.0

- old
+ new

@@ -5,17 +5,17 @@ describe 'Javascript functions', -> describe 'up.observe', -> changeEvents = if up.browser.canInputEvent() -# Actually we only need `input`, but we want to notice -# if another script manually triggers `change` on the element. + # Actually we only need `input`, but we want to notice + # if another script manually triggers `change` on the element. ['input', 'change'] else -# Actually we won't ever get `input` from the user in this browser, -# but we want to notice if another script manually triggers `input` -# on the element. + # Actually we won't ever get `input` from the user in this browser, + # but we want to notice if another script manually triggers `input` + # on the element. ['input', 'change', 'keypress', 'paste', 'cut', 'click', 'propertychange'] u.each changeEvents, (eventName) -> describe 'when the first argument is a form field', -> @@ -81,49 +81,41 @@ u.nextFrame -> expect(callback).not.toHaveBeenCalled() done() describe 'up.submit', -> + + describeCapability 'canPushState', -> - if up.browser.canPushState() - beforeEach -> - $form = affix('form[action="/path/to"][method="put"][up-target=".response"]') - $form.append('<input name="field1" value="value1">') - $form.append('<input name="field2" value="value2">') - + @$form = affix('form[action="/path/to"][method="put"][up-target=".response"]') + @$form.append('<input name="field1" value="value1">') + @$form.append('<input name="field2" value="value2">') affix('.response').text('old-text') - - @promise = up.submit($form) - + @promise = up.submit(@$form) @request = @lastRequest() + + it 'submits the given form and replaces the target with the response', -> expect(@request.url).toMatch /\/path\/to$/ - expect(@request.method).toBe 'PUT' - expect(@request.data()).toEqual - field1: ['value1'] - field2: ['value2'] - - it 'submits the given form and replaces the target with the response', (done) -> - + expect(@request).toHaveRequestMethod('PUT') + expect(@request.data()['field1']).toEqual(['value1']) + expect(@request.data()['field2']).toEqual(['value2']) + expect(@request.requestHeaders['X-Up-Target']).toEqual('.response') + @respondWith """ text-before <div class="response"> new-text </div> text-after """ - - @promise.then -> - expect($('.response')).toHaveText('new-text') - expect($('body')).not.toHaveText('text-before') - expect($('body')).not.toHaveText('text-after') - done() - - it 'places the response into the form if the submission returns a 5xx status code', (done) -> - @request.respondWith + + it "places the response into the form and doesn't update the browser URL if the submission returns a 5xx status code", -> + up.submit(@$form) + @respondWith status: 500 contentType: 'text/html' responseText: """ text-before @@ -132,36 +124,51 @@ error-messages </form> text-after """ - - @promise.always -> - expect($('.response')).toHaveText('old-text') - expect($('form')).toHaveText('error-messages') - expect($('body')).not.toHaveText('text-before') - expect($('body')).not.toHaveText('text-after') - done() - - it 'respects a X-Up-Location header that the server sends in case of a redirect', (done) -> - - @request.respondWith + expect(up.browser.url()).toEqual(@hrefBeforeExample) + expect($('.response')).toHaveText('old-text') + expect($('form')).toHaveText('error-messages') + expect($('body')).not.toHaveText('text-before') + expect($('body')).not.toHaveText('text-after') + + it 'respects X-Up-Method and X-Up-Location response headers so the server can show that it redirected to a GET URL', -> + up.submit(@$form) + @respondWith status: 200 contentType: 'text/html' - responseHeaders: { 'X-Up-Location': '/other/path' } + responseHeaders: + 'X-Up-Location': '/other-path' + 'X-Up-Method': 'GET' responseText: """ <div class="response"> new-text </div> """ - - @promise.then -> - expect(up.browser.url()).toMatch(/\/other\/path$/) - done() - - else + + expect(up.browser.url()).toEndWith('/other-path') + + describe 'with { history } option', -> + + it 'uses the given URL as the new browser location if the request succeeded', -> + up.submit(@$form, history: '/given-path') + @respondWith('<div class="response">new-text</div>') + expect(up.browser.url()).toEndWith('/given-path') + + it 'keeps the current browser location if the request failed', -> + up.submit(@$form, history: '/given-path', failTarget: '.response') + @respondWith('<div class="response">new-text</div>', status: 500) + expect(up.browser.url()).toEqual(@hrefBeforeExample) + + it 'keeps the current browser location if the option is set to false', -> + up.submit(@$form, history: false) + @respondWith('<div class="response">new-text</div>') + expect(up.browser.url()).toEqual(@hrefBeforeExample) + + describeFallback 'canPushState', -> it 'submits the given form', -> $form = affix('form[action="/path/to"][method="put"][up-target=".response"]') form = $form.get(0) spyOn(form, 'submit') @@ -219,11 +226,11 @@ """).appendTo($form) $group.find('input').trigger('change') request = @lastRequest() expect(request.requestHeaders['X-Up-Validate']).toEqual('user') - expect(request.requestHeaders['X-Up-Selector']).toEqual(".field-group:has([name='user'])") + expect(request.requestHeaders['X-Up-Target']).toEqual(".field-group:has([name='user'])") @respondWith """ <div class="field-group has-error"> <div class='error'>Username has already been taken</div> <input name="user" value="judy" up-validate=".field-group:has(&)"> @@ -272,5 +279,193 @@ """ $labels = $('#registration label') expect($labels[0]).not.toHaveText('Validation message') expect($labels[1]).toHaveText('Validation message') + + describe '[up-toggle]', -> + + describe 'on a select', -> + + beforeEach -> + @$select = affix('select[up-toggle=".target"]') + @$blankOption = @$select.affix('option').text('<Please select something>').val('') + @$fooOption = @$select.affix('option[value="foo"]').text('Foo') + @$barOption = @$select.affix('option[value="bar"]').text('Bar') + @$bazOption = @$select.affix('option[value="baz"]').text('Baz') + + it "shows the target element iff its up-show-for attribute contains the select value", -> + $target = affix('.target[up-show-for="something bar other"]') + up.hello(@$select) + expect($target).toBeHidden() + @$select.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-hide-for attribute doesn't contain the select value", -> + $target = affix('.target[up-hide-for="something bar other"]') + up.hello(@$select) + expect($target).toBeVisible() + @$select.val('bar').change() + expect($target).toBeHidden() + + it "shows the target element iff it has neither up-show-for nor up-hide-for and the select value is present", -> + $target = affix('.target') + up.hello(@$select) + expect($target).toBeHidden() + @$select.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':present' and the select value is present", -> + $target = affix('.target[up-show-for=":present"]') + up.hello(@$select) + expect($target).toBeHidden() + @$select.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':blank' and the select value is blank", -> + $target = affix('.target[up-show-for=":blank"]') + up.hello(@$select) + expect($target).toBeVisible() + @$select.val('bar').change() + expect($target).toBeHidden() + + describe 'on a checkbox', -> + + beforeEach -> + @$checkbox = affix('input[type="checkbox"][value="1"][up-toggle=".target"]') + + it "shows the target element iff its up-show-for attribute is :checked and the checkbox is checked", -> + $target = affix('.target[up-show-for=":checked"]') + up.hello(@$checkbox) + expect($target).toBeHidden() + @$checkbox.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute is :unchecked and the checkbox is unchecked", -> + $target = affix('.target[up-show-for=":unchecked"]') + up.hello(@$checkbox) + expect($target).toBeVisible() + @$checkbox.prop('checked', true).change() + expect($target).toBeHidden() + + it "shows the target element iff its up-hide-for attribute is :checked and the checkbox is unchecked", -> + $target = affix('.target[up-hide-for=":checked"]') + up.hello(@$checkbox) + expect($target).toBeVisible() + @$checkbox.prop('checked', true).change() + expect($target).toBeHidden() + + it "shows the target element iff its up-hide-for attribute is :unchecked and the checkbox is checked", -> + $target = affix('.target[up-hide-for=":unchecked"]') + up.hello(@$checkbox) + expect($target).toBeHidden() + @$checkbox.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff it has neither up-show-for nor up-hide-for and the checkbox is checked", -> + $target = affix('.target') + up.hello(@$checkbox) + expect($target).toBeHidden() + @$checkbox.prop('checked', true).change() + expect($target).toBeVisible() + + describe 'on a group of radio buttons', -> + + beforeEach -> + @$buttons = affix('.radio-buttons') + @$blankButton = @$buttons.affix('input[type="radio"][name="group"][up-toggle=".target"]').val('') + @$fooButton = @$buttons.affix('input[type="radio"][name="group"][up-toggle=".target"]').val('foo') + @$barButton = @$buttons.affix('input[type="radio"][name="group"][up-toggle=".target"]').val('bar') + @$bazkButton = @$buttons.affix('input[type="radio"][name="group"][up-toggle=".target"]').val('baz') + + it "shows the target element iff its up-show-for attribute contains the selected button value", -> + $target = affix('.target[up-show-for="something bar other"]') + up.hello(@$buttons) + expect($target).toBeHidden() + @$barButton.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff its up-hide-for attribute doesn't contain the selected button value", -> + $target = affix('.target[up-hide-for="something bar other"]') + up.hello(@$buttons) + expect($target).toBeVisible() + @$barButton.prop('checked', true).change() + expect($target).toBeHidden() + + it "shows the target element iff it has neither up-show-for nor up-hide-for and the selected button value is present", -> + $target = affix('.target') + up.hello(@$buttons) + expect($target).toBeHidden() + @$barButton.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':present' and the selected button value is present", -> + $target = affix('.target[up-show-for=":present"]') + up.hello(@$buttons) + expect($target).toBeHidden() + @$blankButton.prop('checked', true).change() + expect($target).toBeHidden() + @$barButton.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':blank' and the selected button value is blank", -> + $target = affix('.target[up-show-for=":blank"]') + up.hello(@$buttons) + expect($target).toBeVisible() + @$blankButton.prop('checked', true).change() + expect($target).toBeVisible() + @$barButton.prop('checked', true).change() + expect($target).toBeHidden() + + it "shows the target element iff its up-show-for attribute contains a value ':checked' and any button is checked", -> + $target = affix('.target[up-show-for=":checked"]') + up.hello(@$buttons) + expect($target).toBeHidden() + @$blankButton.prop('checked', true).change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':unchecked' and no button is checked", -> + $target = affix('.target[up-show-for=":unchecked"]') + up.hello(@$buttons) + expect($target).toBeVisible() + @$blankButton.prop('checked', true).change() + expect($target).toBeHidden() + + describe 'on a text input', -> + + beforeEach -> + @$textInput = affix('input[type="text"][up-toggle=".target"]') + + it "shows the target element iff its up-show-for attribute contains the input value", -> + $target = affix('.target[up-show-for="something bar other"]') + up.hello(@$textInput) + expect($target).toBeHidden() + @$textInput.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-hide-for attribute doesn't contain the input value", -> + $target = affix('.target[up-hide-for="something bar other"]') + up.hello(@$textInput) + expect($target).toBeVisible() + @$textInput.val('bar').change() + expect($target).toBeHidden() + + it "shows the target element iff it has neither up-show-for nor up-hide-for and the input value is present", -> + $target = affix('.target') + up.hello(@$textInput) + expect($target).toBeHidden() + @$textInput.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':present' and the input value is present", -> + $target = affix('.target[up-show-for=":present"]') + up.hello(@$textInput) + expect($target).toBeHidden() + @$textInput.val('bar').change() + expect($target).toBeVisible() + + it "shows the target element iff its up-show-for attribute contains a value ':blank' and the input value is blank", -> + $target = affix('.target[up-show-for=":blank"]') + up.hello(@$textInput) + expect($target).toBeVisible() + @$textInput.val('bar').change() + expect($target).toBeHidden()