praxis 0.16.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.ruby-version +1 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +41 -0
- data/CONTRIBUTING.md +3 -0
- data/lib/api_browser/Gruntfile.js +20 -4
- data/lib/api_browser/app/bower_components/angular-mocks/.bower.json +6 -6
- data/lib/api_browser/app/bower_components/angular-mocks/README.md +11 -5
- data/lib/api_browser/app/bower_components/angular-mocks/angular-mocks.js +475 -216
- data/lib/api_browser/app/bower_components/angular-mocks/bower.json +2 -2
- data/lib/api_browser/app/bower_components/angular-mocks/ngAnimateMock.js +2 -0
- data/lib/api_browser/app/bower_components/angular-mocks/ngMock.js +2 -0
- data/lib/api_browser/app/bower_components/angular-mocks/ngMockE2E.js +2 -0
- data/lib/api_browser/app/bower_components/angular-mocks/package.json +1 -1
- data/lib/api_browser/app/bower_components/angular-sanitize/.bower.json +8 -8
- data/lib/api_browser/app/bower_components/angular-sanitize/README.md +19 -5
- data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.js +186 -127
- data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js +12 -10
- data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js.map +3 -3
- data/lib/api_browser/app/bower_components/angular-sanitize/bower.json +3 -2
- data/lib/api_browser/app/bower_components/angular-sanitize/index.js +2 -0
- data/lib/api_browser/app/bower_components/angular-sanitize/package.json +26 -0
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/.bower.json +15 -8
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/bower.json +11 -3
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-csp.css +6 -0
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js +1177 -453
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js +4 -4
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.js +1066 -404
- data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js +3 -3
- data/lib/api_browser/app/bower_components/angular-ui-router/.bower.json +5 -6
- data/lib/api_browser/app/bower_components/angular-ui-router/CHANGELOG.md +208 -3
- data/lib/api_browser/app/bower_components/angular-ui-router/CONTRIBUTING.md +65 -0
- data/lib/api_browser/app/bower_components/angular-ui-router/LICENSE +1 -1
- data/lib/api_browser/app/bower_components/angular-ui-router/README.md +36 -71
- data/lib/api_browser/app/bower_components/angular-ui-router/api/angular-ui-router.d.ts +126 -0
- data/lib/api_browser/app/bower_components/angular-ui-router/bower.json +1 -1
- data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.js +1902 -755
- data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.min.js +2 -2
- data/lib/api_browser/app/bower_components/angular-ui-router/src/common.js +69 -23
- data/lib/api_browser/app/bower_components/angular-ui-router/src/resolve.js +15 -5
- data/lib/api_browser/app/bower_components/angular-ui-router/src/state.js +556 -295
- data/lib/api_browser/app/bower_components/angular-ui-router/src/stateDirectives.js +101 -42
- data/lib/api_browser/app/bower_components/angular-ui-router/src/stateFilters.js +6 -2
- data/lib/api_browser/app/bower_components/angular-ui-router/src/templateFactory.js +2 -2
- data/lib/api_browser/app/bower_components/angular-ui-router/src/urlMatcherFactory.js +822 -97
- data/lib/api_browser/app/bower_components/angular-ui-router/src/urlRouter.js +274 -120
- data/lib/api_browser/app/bower_components/angular-ui-router/src/viewDirective.js +33 -20
- data/lib/api_browser/app/bower_components/angular-ui-router/src/viewScroll.js +1 -1
- data/lib/api_browser/app/bower_components/angular/.bower.json +5 -5
- data/lib/api_browser/app/bower_components/angular/README.md +2 -5
- data/lib/api_browser/app/bower_components/angular/angular-csp.css +5 -8
- data/lib/api_browser/app/bower_components/angular/angular.js +12975 -6996
- data/lib/api_browser/app/bower_components/angular/angular.min.js +285 -213
- data/lib/api_browser/app/bower_components/angular/angular.min.js.gzip +0 -0
- data/lib/api_browser/app/bower_components/angular/angular.min.js.map +3 -3
- data/lib/api_browser/app/bower_components/angular/bower.json +1 -1
- data/lib/api_browser/app/bower_components/angular/index.js +2 -0
- data/lib/api_browser/app/bower_components/angular/package.json +2 -2
- data/lib/api_browser/app/bower_components/bootstrap-sass/.bower.json +31 -16
- data/lib/api_browser/app/bower_components/bootstrap-sass/CHANGELOG.md +108 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/CONTRIBUTING.md +55 -37
- data/lib/api_browser/app/bower_components/bootstrap-sass/README.md +147 -206
- data/lib/api_browser/app/bower_components/bootstrap-sass/bower.json +19 -8
- data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.eot +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.svg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.ttf +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.woff +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap.js +12 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/affix.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/alert.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/button.js +11 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/carousel.js +5 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/collapse.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/dropdown.js +5 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/modal.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/popover.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/scrollspy.js +2 -2
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tab.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tooltip.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/transition.js +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap.scss +1 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_alerts.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_badges.scss +6 -6
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_breadcrumbs.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_button-groups.scss +7 -33
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_buttons.scss +2 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_carousel.scss +1 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_close.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_code.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_component-animations.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_dropdowns.scss +3 -8
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_forms.scss +11 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_glyphicons.scss +5 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_grid.scss +12 -26
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_input-groups.scss +1 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_jumbotron.scss +8 -2
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_labels.scss +6 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_list-group.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_media.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_mixins.scss +38 -51
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_modals.scss +2 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navbar.scss +41 -53
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navs.scss +0 -20
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_normalize.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pager.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pagination.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_panels.scss +11 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_popovers.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_print.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_progress-bars.scss +0 -12
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_responsive-utilities.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_scaffolding.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tables.scss +5 -18
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_theme.scss +2 -2
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_thumbnails.scss +9 -3
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tooltip.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_type.scss +54 -52
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_utilities.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_variables.scss +20 -11
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_wells.scss +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/bootstrap.scss +0 -0
- data/lib/api_browser/app/bower_components/lodash/.bower.json +9 -13
- data/lib/api_browser/app/bower_components/lodash/LICENSE.txt +3 -3
- data/lib/api_browser/app/bower_components/lodash/bower.json +4 -7
- data/lib/api_browser/app/bower_components/lodash/lodash.js +12235 -0
- data/lib/api_browser/app/bower_components/lodash/lodash.min.js +98 -0
- data/lib/api_browser/app/index.html +0 -1
- data/lib/api_browser/app/js/app.js +2 -5
- data/lib/api_browser/app/js/controllers/action.js +21 -37
- data/lib/api_browser/app/js/controllers/controller.js +23 -1
- data/lib/api_browser/app/js/controllers/menu.js +46 -14
- data/lib/api_browser/app/js/controllers/type.js +2 -9
- data/lib/api_browser/app/js/directives/attribute_description.js +15 -5
- data/lib/api_browser/app/js/directives/attribute_table.js +6 -6
- data/lib/api_browser/app/js/directives/fixed_if_fits.js +20 -0
- data/lib/api_browser/app/js/directives/no_container.js +6 -6
- data/lib/api_browser/app/js/directives/type_placeholder.js +21 -0
- data/lib/api_browser/app/js/factories/Configuration.js +13 -0
- data/lib/api_browser/app/js/factories/Documentation.js +0 -3
- data/lib/api_browser/app/js/factories/normalize_attributes.js +19 -0
- data/lib/api_browser/app/js/factories/template_for.js +113 -0
- data/lib/api_browser/app/sass/modules/_body.scss +26 -4
- data/lib/api_browser/app/sass/modules/_sidebar.scss +68 -1
- data/lib/api_browser/app/sass/praxis.scss +1 -5
- data/lib/api_browser/app/sass/variables/_bootstrap-variables.scss +13 -4
- data/lib/api_browser/app/views/action.html +13 -17
- data/lib/api_browser/app/views/controller.html +32 -4
- data/lib/api_browser/app/views/directives/attribute_description.html +1 -1
- data/lib/api_browser/app/views/directives/attribute_description/{_default.html → default.html} +0 -0
- data/lib/api_browser/app/views/directives/attribute_description/example.html +13 -0
- data/lib/api_browser/app/views/directives/attribute_description/headers.html +8 -0
- data/lib/api_browser/app/views/directives/attribute_description/member_options.html +4 -0
- data/lib/api_browser/app/views/directives/attribute_description/values.html +14 -0
- data/lib/api_browser/app/views/directives/attribute_table.html +2 -2
- data/lib/api_browser/app/views/home.html +1 -3
- data/lib/api_browser/app/views/layout.html +3 -36
- data/lib/api_browser/app/views/menu.html +45 -0
- data/lib/api_browser/app/views/navbar.html +1 -1
- data/lib/api_browser/app/views/type.html +2 -2
- data/lib/api_browser/app/views/type/{_details.html → details.html} +6 -6
- data/lib/api_browser/app/views/types/embedded/default.html +10 -0
- data/lib/api_browser/app/views/types/embedded/links.html +11 -0
- data/lib/api_browser/app/views/types/embedded/struct.html +2 -0
- data/lib/api_browser/app/views/types/label/link.html +1 -0
- data/lib/api_browser/app/views/types/label/primitive.html +1 -0
- data/lib/api_browser/app/views/types/label/primitive_collection.html +1 -0
- data/lib/api_browser/app/views/types/label/type.html +1 -0
- data/lib/api_browser/app/views/types/label/type_collection.html +1 -0
- data/lib/api_browser/app/views/{directives/request_body/_default.html → types/standalone/default.html} +1 -1
- data/lib/api_browser/app/views/types/standalone/struct.html +1 -0
- data/lib/api_browser/bower.json +9 -9
- data/lib/api_browser/package.json +1 -1
- data/lib/praxis.rb +10 -4
- data/lib/praxis/action_definition.rb +16 -4
- data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -2
- data/lib/praxis/api_definition.rb +3 -1
- data/lib/praxis/api_general_info.rb +49 -5
- data/lib/praxis/application.rb +12 -4
- data/lib/praxis/bootloader.rb +1 -0
- data/lib/praxis/bootloader_stages/environment.rb +2 -0
- data/lib/praxis/bootloader_stages/routing.rb +1 -1
- data/lib/praxis/bootloader_stages/subgroup_loader.rb +1 -0
- data/lib/praxis/exceptions/validation.rb +7 -0
- data/lib/praxis/handlers/plain.rb +16 -0
- data/lib/praxis/handlers/xml.rb +4 -4
- data/lib/praxis/links.rb +13 -3
- data/lib/praxis/media_type_identifier.rb +3 -0
- data/lib/praxis/multipart/parser.rb +41 -48
- data/lib/praxis/multipart/part.rb +196 -3
- data/lib/praxis/request.rb +14 -11
- data/lib/praxis/request_stages/request_stage.rb +4 -0
- data/lib/praxis/request_stages/response.rb +10 -9
- data/lib/praxis/request_stages/validate.rb +1 -7
- data/lib/praxis/request_stages/validate_params_and_headers.rb +30 -5
- data/lib/praxis/request_stages/validate_payload.rb +14 -5
- data/lib/praxis/resource_definition.rb +117 -15
- data/lib/praxis/response.rb +6 -5
- data/lib/praxis/response_definition.rb +51 -5
- data/lib/praxis/responses/http.rb +5 -0
- data/lib/praxis/responses/multipart_ok.rb +51 -0
- data/lib/praxis/responses/validation_error.rb +7 -7
- data/lib/praxis/restful_doc_generator.rb +9 -4
- data/lib/praxis/route.rb +3 -2
- data/lib/praxis/router.rb +26 -16
- data/lib/praxis/router/rack.rb +51 -0
- data/lib/praxis/router/simple.rb +146 -0
- data/lib/praxis/routing_config.rb +2 -2
- data/lib/praxis/trait.rb +1 -1
- data/lib/praxis/types/fuzzy_hash.rb +49 -0
- data/lib/praxis/types/media_type_common.rb +1 -1
- data/lib/praxis/types/multipart.rb +47 -12
- data/lib/praxis/types/multipart_array.rb +320 -0
- data/lib/praxis/types/multipart_array/part_definition.rb +52 -0
- data/lib/praxis/validation_handler.rb +10 -0
- data/lib/praxis/version.rb +2 -2
- data/praxis.gemspec +3 -3
- data/spec/api_browser/directives/type_placeholder_spec.js +134 -0
- data/spec/api_browser/factories/normalize_attributes_spec.js +97 -0
- data/spec/api_browser/factories/template_for_spec.js +67 -0
- data/spec/functional_spec.rb +111 -45
- data/spec/praxis/action_definition_spec.rb +31 -7
- data/spec/praxis/api_definition_spec.rb +2 -2
- data/spec/praxis/api_general_info_spec.rb +25 -0
- data/spec/praxis/application_spec.rb +24 -11
- data/spec/praxis/handlers/xml_spec.rb +55 -33
- data/spec/praxis/links_spec.rb +18 -1
- data/spec/praxis/media_type_collection_spec.rb +1 -1
- data/spec/praxis/media_type_spec.rb +2 -2
- data/spec/praxis/multipart/parser_spec.rb +21 -13
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +1 -1
- data/spec/praxis/request_spec.rb +52 -24
- data/spec/praxis/{request_stages_action_spec.rb → request_stages/action_spec.rb} +1 -1
- data/spec/praxis/{request_stage_spec.rb → request_stages/request_stage_spec.rb} +0 -0
- data/spec/praxis/{request_stages_validate_spec.rb → request_stages/validate_spec.rb} +1 -1
- data/spec/praxis/resource_definition_spec.rb +30 -4
- data/spec/praxis/response_definition_spec.rb +60 -19
- data/spec/praxis/response_spec.rb +2 -2
- data/spec/praxis/responses/validation_error_spec.rb +33 -16
- data/spec/praxis/route_spec.rb +4 -2
- data/spec/praxis/router_spec.rb +28 -12
- data/spec/praxis/routing_config_spec.rb +11 -5
- data/spec/praxis/types/collection_spec.rb +1 -1
- data/spec/praxis/types/fuzzy_hash_spec.rb +20 -0
- data/spec/praxis/types/multipart_array/part_definition_spec.rb +5 -0
- data/spec/praxis/types/multipart_array_spec.rb +334 -0
- data/spec/praxis/types/multipart_spec.rb +14 -5
- data/spec/spec_app/app/controllers/instances.rb +20 -10
- data/spec/spec_app/app/controllers/volumes.rb +8 -4
- data/spec/spec_app/app/responses/bulk_response.rb +0 -6
- data/spec/spec_app/config/environment.rb +13 -0
- data/spec/spec_app/design/api.rb +7 -10
- data/spec/spec_app/design/media_types/instance.rb +3 -1
- data/spec/spec_app/design/resources/instances.rb +50 -41
- data/spec/spec_app/design/resources/volume_snapshots.rb +39 -0
- data/spec/spec_app/design/resources/volumes.rb +11 -6
- data/spec/spec_helper.rb +3 -1
- metadata +125 -218
- data/lib/api_browser/app/bower_components/angular-ui-router/src/compat.js +0 -146
- data/lib/api_browser/app/bower_components/bootstrap-sass/CNAME +0 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/DOCS-LICENSE +0 -319
- data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile +0 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile.lock +0 -14
- data/lib/api_browser/app/bower_components/bootstrap-sass/Gruntfile.js +0 -244
- data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE +0 -176
- data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE-MIT +0 -21
- data/lib/api_browser/app/bower_components/bootstrap-sass/Rakefile +0 -44
- data/lib/api_browser/app/bower_components/bootstrap-sass/_config.yml +0 -25
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/ads.html +0 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/footer.html +0 -34
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/header.html +0 -42
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-about.html +0 -12
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-components.html +0 -137
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-css.html +0 -99
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-customize.html +0 -40
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-getting-started.html +0 -44
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-javascript.html +0 -88
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-main.html +0 -37
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/old-bs-docs.html +0 -8
- data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/social-buttons.html +0 -16
- data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/default.html +0 -79
- data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/home.html +0 -47
- data/lib/api_browser/app/bower_components/bootstrap-sass/about.html +0 -93
- data/lib/api_browser/app/bower_components/bootstrap-sass/browserstack.json +0 -37
- data/lib/api_browser/app/bower_components/bootstrap-sass/components.html +0 -3689
- data/lib/api_browser/app/bower_components/bootstrap-sass/composer.json +0 -28
- data/lib/api_browser/app/bower_components/bootstrap-sass/css.html +0 -2674
- data/lib/api_browser/app/bower_components/bootstrap-sass/customize.html +0 -1715
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.css +0 -427
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.min.css +0 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.css +0 -6350
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.min.css +0 -1
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.js +0 -2002
- data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.min.js +0 -9
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/docs.css +0 -1195
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/pygments-manni.css +0 -66
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/apple-touch-icon-144-precomposed.png +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/favicon.png +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/application.js +0 -103
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/customizer.js +0 -332
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/filesaver.js +0 -169
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/holder.js +0 -404
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/ie8-responsive-file-warning.js +0 -12
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/jszip.js +0 -1467
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/less.js +0 -9
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/raw-files.js +0 -3
- data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/uglify.js +0 -14
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/carousel.css +0 -148
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/index.html +0 -206
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/grid.css +0 -28
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/index.html +0 -148
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/index.html +0 -82
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/jumbotron-narrow.css +0 -79
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/index.html +0 -99
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/jumbotron.css +0 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/index.html +0 -83
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/justified-nav.css +0 -88
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/index.html +0 -91
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/navbar-fixed-top.css +0 -4
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/index.html +0 -92
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/navbar-static-top.css +0 -7
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/index.html +0 -88
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/navbar.css +0 -8
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/index.html +0 -101
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/non-responsive.css +0 -116
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/index.html +0 -130
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.css +0 -50
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.js +0 -5
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/carousel.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/grid.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron-narrow.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/justified-nav.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-fixed.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-static.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/non-responsive.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/offcanvas.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sign-in.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/starter-template.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer-navbar.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/theme.jpg +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/index.html +0 -50
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/signin.css +0 -40
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/index.html +0 -68
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/starter-template.css +0 -7
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/index.html +0 -91
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/sticky-footer-navbar.css +0 -45
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/index.html +0 -55
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/sticky-footer.css +0 -38
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/index.html +0 -384
- data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/theme.css +0 -14
- data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.svg +0 -229
- data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/api_browser/app/bower_components/bootstrap-sass/getting-started.html +0 -1021
- data/lib/api_browser/app/bower_components/bootstrap-sass/index.html +0 -16
- data/lib/api_browser/app/bower_components/bootstrap-sass/javascript.html +0 -1983
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/index.html +0 -52
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/affix.js +0 -25
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/alert.js +0 -62
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/button.js +0 -116
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/carousel.js +0 -87
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/collapse.js +0 -164
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/dropdown.js +0 -219
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/modal.js +0 -196
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/phantom.js +0 -69
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/popover.js +0 -133
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/scrollspy.js +0 -37
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tab.js +0 -86
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tooltip.js +0 -437
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/transition.js +0 -13
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/jquery.js +0 -6
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.css +0 -232
- data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.js +0 -1510
- data/lib/api_browser/app/bower_components/bootstrap-sass/package.json +0 -40
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.js +0 -7157
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.min.js +0 -61
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.js +0 -6785
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.min.js +0 -56
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.js +0 -4979
- data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.min.js +0 -39
- data/lib/api_browser/app/js/directives/attribute_table_row.js +0 -17
- data/lib/api_browser/app/js/directives/request_body.js +0 -25
- data/lib/api_browser/app/js/directives/request_headers.js +0 -17
- data/lib/api_browser/app/js/directives/request_parameters.js +0 -17
- data/lib/api_browser/app/js/directives/type_label.js +0 -52
- data/lib/api_browser/app/js/factories/PayloadTemplates.js +0 -10
- data/lib/api_browser/app/js/factories/TemplateProvider.js +0 -45
- data/lib/api_browser/app/js/factories/TypeTemplates.js +0 -11
- data/lib/api_browser/app/views/directives/attribute_description/_example.html +0 -13
- data/lib/api_browser/app/views/directives/attribute_description/_headers.html +0 -8
- data/lib/api_browser/app/views/directives/attribute_table_row/_default.html +0 -10
- data/lib/api_browser/app/views/directives/attribute_table_row/_links.html +0 -11
- data/lib/api_browser/app/views/directives/attribute_table_row/_struct.html +0 -2
- data/lib/api_browser/app/views/directives/request_body/_struct.html +0 -1
- data/lib/api_browser/app/views/resource/_actions.html +0 -27
data/spec/praxis/route_spec.rb
CHANGED
@@ -3,17 +3,19 @@ require 'spec_helper'
|
|
3
3
|
describe Praxis::Route do
|
4
4
|
|
5
5
|
let(:verb) { 'GET' }
|
6
|
-
let(:path) { '/stuff' }
|
6
|
+
let(:path) { '/base/stuff' }
|
7
|
+
let(:prefixed_path) { '/stuff' }
|
7
8
|
let(:name) { nil }
|
8
9
|
let(:version) { '1.0' }
|
9
10
|
let(:options) { {} }
|
10
11
|
|
11
|
-
subject(:route) { Praxis::Route.new(verb, path, version, name: name, **options) }
|
12
|
+
subject(:route) { Praxis::Route.new(verb, path, version, name: name, prefixed_path: prefixed_path, **options) }
|
12
13
|
|
13
14
|
its(:verb) { should be(verb) }
|
14
15
|
its(:path) { should be(path) }
|
15
16
|
its(:name) { should be(name) }
|
16
17
|
its(:version) { should be(version) }
|
18
|
+
its(:prefixed_path) { should eq(prefixed_path) }
|
17
19
|
its(:options) { should eq(options) }
|
18
20
|
|
19
21
|
it 'defaults version to "n/a"' do
|
data/spec/praxis/router_spec.rb
CHANGED
@@ -19,14 +19,14 @@ describe Praxis::Router do
|
|
19
19
|
let(:env){ {"HTTP_X_API_VERSION" => request_version } }
|
20
20
|
let(:request) {Praxis::Request.new(env)}
|
21
21
|
|
22
|
-
#let(:request){ double("request", version: request_version, env: env ) }
|
23
22
|
context 'with matching versions' do
|
24
23
|
let(:request_version) { "1.0" }
|
25
24
|
it 'calls the target' do
|
26
|
-
expect(
|
25
|
+
expect(target).to receive(:call).with(request)
|
27
26
|
matcher.call(request)
|
28
27
|
end
|
29
28
|
end
|
29
|
+
|
30
30
|
context 'with non-matching versions' do
|
31
31
|
let(:request_version) { "4.0" }
|
32
32
|
before do
|
@@ -80,14 +80,21 @@ describe Praxis::Router do
|
|
80
80
|
let(:target){ double('target') }
|
81
81
|
let(:verb_router){ double('verb_router') }
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
let(:resource_definition) { double('resource_definition', version_options: {using: [:header, :params]} ) }
|
84
|
+
let(:action) { double('action', resource_definition: resource_definition) }
|
85
|
+
let(:target) { double('target', action: action) }
|
86
|
+
|
87
|
+
|
88
|
+
context 'with params or header versioning' do
|
89
|
+
it 'wraps the target with a VersionMatcher' do
|
90
|
+
router.instance_variable_set( :@routes, {'verb'=>verb_router} ) # Ugly, but no need to have a reader
|
91
|
+
expect(verb_router).to receive(:on) do|path, args|# .with(route.path, call: "foo")
|
92
|
+
expect(path).to eq(route.path)
|
93
|
+
expect(args).to be_kind_of(Hash)
|
94
|
+
expect(args[:call]).to be_kind_of(Praxis::Router::VersionMatcher)
|
95
|
+
end
|
96
|
+
router.add_route(target, route)
|
89
97
|
end
|
90
|
-
router.add_route(target ,route)
|
91
98
|
end
|
92
99
|
|
93
100
|
end
|
@@ -103,13 +110,18 @@ describe Praxis::Router do
|
|
103
110
|
let(:router_response_for_wildcard){ "* result" }
|
104
111
|
let(:post_target_router){ double("POST target", call: router_response_for_post) }
|
105
112
|
let(:any_target_router){ double("ANY target", call: router_response_for_wildcard) }
|
113
|
+
|
114
|
+
let(:resource_definition) { double('resource_definition', version_options: {using: [:header, :params]} ) }
|
115
|
+
let(:action) { double('action', resource_definition: resource_definition) }
|
116
|
+
let(:target) { double('target', action: action) }
|
117
|
+
|
106
118
|
before do
|
107
119
|
env['HTTP_X_API_VERSION'] = request_version if request_version
|
108
120
|
allow_any_instance_of(Praxis::Router::RequestRouter).
|
109
121
|
to receive(:call).with(request).and_return(router_response)
|
110
|
-
router.add_route(
|
122
|
+
router.add_route(target,double("route1", verb: 'POST', path: '/', options: {} , version: request_version))
|
111
123
|
# Hijack the callable block in the routes (since there's no way to point back to the registered route object)
|
112
|
-
router.instance_variable_get(
|
124
|
+
router.instance_variable_get(:@routes)['POST'] = post_target_router
|
113
125
|
|
114
126
|
end
|
115
127
|
|
@@ -130,8 +142,12 @@ describe Praxis::Router do
|
|
130
142
|
end
|
131
143
|
|
132
144
|
context 'for routes with wildcards (a POST and a * route)' do
|
145
|
+
let(:resource_definition) { double('resource_definition', version_options: {using: [:header, :params]} ) }
|
146
|
+
let(:action) { double('action', resource_definition: resource_definition) }
|
147
|
+
let(:target) { double('target', action: action) }
|
148
|
+
|
133
149
|
before do
|
134
|
-
router.add_route(
|
150
|
+
router.add_route(target,double("route2", verb: 'ANY', path: '/*', options: {} , version: request_version))
|
135
151
|
# Hijack the callable block in the routes (since there's no way to point back to the registered route object)
|
136
152
|
router.instance_variable_get( :@routes )['ANY'] = any_target_router
|
137
153
|
end
|
@@ -10,9 +10,10 @@ describe Praxis::RoutingConfig do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
let(:routing_block) { Proc.new{} }
|
13
|
+
let(:base_path){ '' }
|
13
14
|
let(:default_route_prefix) { "/" + resource_definition.name.split("::").last.underscore }
|
14
15
|
|
15
|
-
subject(:routing_config){ Praxis::RoutingConfig.new(&routing_block) }
|
16
|
+
subject(:routing_config){ Praxis::RoutingConfig.new(base: base_path, &routing_block) }
|
16
17
|
|
17
18
|
its(:version) { should eq('n/a') }
|
18
19
|
its(:prefix ) { should eq('') }
|
@@ -40,6 +41,7 @@ describe Praxis::RoutingConfig do
|
|
40
41
|
context '#add_route' do
|
41
42
|
let(:path) { '/people' }
|
42
43
|
let(:options) { {} }
|
44
|
+
let(:base_path){ '/api' }
|
43
45
|
let(:route) { routing_config.add_route 'GET', path, **options}
|
44
46
|
|
45
47
|
it 'returns a corresponding Praxis::Route' do
|
@@ -58,12 +60,12 @@ describe Praxis::RoutingConfig do
|
|
58
60
|
end
|
59
61
|
|
60
62
|
it 'does NOT pass the name option down to mustermann' do
|
61
|
-
expect(Mustermann).to receive(:new).with(path, hash_excluding({name: 'alternative'}))
|
63
|
+
expect(Mustermann).to receive(:new).with(base_path + path, hash_excluding({name: 'alternative'}))
|
62
64
|
expect(route.name).to eq('alternative')
|
63
65
|
end
|
64
66
|
|
65
67
|
it 'passes them through the underlying mustermann object (telling it to ignore unknown ones)' do
|
66
|
-
expect(Mustermann).to receive(:new).with(path, hash_including(ignore_unknown_options: true, except: '/special'))
|
68
|
+
expect(Mustermann).to receive(:new).with(base_path + path, hash_including(ignore_unknown_options: true, except: '/special'))
|
67
69
|
expect(route.options).to eq( { except: '/special' })
|
68
70
|
end
|
69
71
|
end
|
@@ -74,13 +76,17 @@ describe Praxis::RoutingConfig do
|
|
74
76
|
end
|
75
77
|
|
76
78
|
it 'includes the prefix in the route path' do
|
77
|
-
expect(route.path.to_s).to eq '/parents/:parent_id/people'
|
79
|
+
expect(route.path.to_s).to eq '/api/parents/:parent_id/people'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has the right prefixed_path' do
|
83
|
+
expect(route.prefixed_path).to eq '/parents/:parent_id/people'
|
78
84
|
end
|
79
85
|
|
80
86
|
context 'for paths beginning with //' do
|
81
87
|
let(:path) { '//people' }
|
82
88
|
it 'does not include the prefix in the route path' do
|
83
|
-
expect(route.path.to_s).to eq '/people'
|
89
|
+
expect(route.path.to_s).to eq '/api/people'
|
84
90
|
end
|
85
91
|
end
|
86
92
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Praxis::Types::FuzzyHash do
|
4
|
+
|
5
|
+
let(:initial_value) {{
|
6
|
+
'key' => 'value',
|
7
|
+
/bob/ => 'rob',
|
8
|
+
/\d+/ => 'one'
|
9
|
+
}}
|
10
|
+
|
11
|
+
subject(:hash) { Praxis::Types::FuzzyHash.new(initial_value) }
|
12
|
+
|
13
|
+
its(['key']) { should eq 'value' }
|
14
|
+
its([/bob/]) { should eq 'rob' }
|
15
|
+
its(['bobby']) { should eq 'rob' }
|
16
|
+
|
17
|
+
its([1]) { should eq 'one' }
|
18
|
+
its(['1']) { should eq 'one' }
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,334 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Praxis::Types::MultipartArray do
|
4
|
+
|
5
|
+
let(:type) do
|
6
|
+
Class.new(Praxis::Types::MultipartArray) do
|
7
|
+
self.options[:case_insensitive_load] = true
|
8
|
+
|
9
|
+
part 'title', String, required: true
|
10
|
+
part(/nam/, String, regexp: /Bob/i)
|
11
|
+
|
12
|
+
part /stuff/ do
|
13
|
+
payload Hash
|
14
|
+
end
|
15
|
+
|
16
|
+
file 'files', multiple: true do
|
17
|
+
header 'Content-Type', 'application/octet-stream'
|
18
|
+
filename String, regexp: /file/
|
19
|
+
payload Attributor::Tempfile
|
20
|
+
end
|
21
|
+
|
22
|
+
part 'image', Attributor::Tempfile, filename: true
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
let(:form) do
|
29
|
+
form_data = MIME::Multipart::FormData.new
|
30
|
+
entity = MIME::Text.new('Bob')
|
31
|
+
form_data.add entity,'name'
|
32
|
+
|
33
|
+
entity = MIME::Text.new('Captain')
|
34
|
+
form_data.add entity,'title'
|
35
|
+
|
36
|
+
entity = MIME::Application.new('file1')
|
37
|
+
form_data.add entity,'files', 'file1'
|
38
|
+
|
39
|
+
entity = MIME::Application.new('file2')
|
40
|
+
form_data.add entity,'files', 'file2'
|
41
|
+
|
42
|
+
entity = MIME::Application.new('
|
43
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
44
|
+
<hash>
|
45
|
+
<first_name>James</first_name>
|
46
|
+
</hash>
|
47
|
+
', 'xml')
|
48
|
+
form_data.add entity,'stuff1'
|
49
|
+
|
50
|
+
entity = MIME::Application.new('{"first_name": "Frank"}', 'json')
|
51
|
+
form_data.add entity,'stuff2'
|
52
|
+
|
53
|
+
entity = MIME::Application.new('', 'jpg')
|
54
|
+
form_data.add entity,'image', 'image.jpg'
|
55
|
+
|
56
|
+
form_data
|
57
|
+
end
|
58
|
+
|
59
|
+
let(:content_type) { form.headers.get('Content-Type') }
|
60
|
+
let(:body) { form.body.to_s }
|
61
|
+
|
62
|
+
subject(:payload) { type.load(body, content_type: content_type) }
|
63
|
+
|
64
|
+
it 'validates' do
|
65
|
+
part = payload.part('files').first
|
66
|
+
expect(payload.validate).to be_empty
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'loads parts correctly' do
|
70
|
+
expect(payload.part('name')).to be_kind_of(Praxis::MultipartPart)
|
71
|
+
expect(payload.part('name').payload).to eq 'Bob'
|
72
|
+
|
73
|
+
title = payload.part('title')
|
74
|
+
expect(title.payload).to eq 'Captain'
|
75
|
+
|
76
|
+
files = payload.part('files')
|
77
|
+
expect(files).to have(2).items
|
78
|
+
|
79
|
+
stuff1 = payload.part('stuff1')
|
80
|
+
expect(stuff1.payload['first_name']).to eq 'James'
|
81
|
+
|
82
|
+
stuff2 = payload.part('stuff2')
|
83
|
+
expect(stuff2.payload['first_name']).to eq 'Frank'
|
84
|
+
|
85
|
+
image = payload.part('image')
|
86
|
+
expect(image.filename).to eq 'image.jpg'
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with only payload_type defined' do
|
90
|
+
let(:type) do
|
91
|
+
Class.new(Praxis::Types::MultipartArray) do
|
92
|
+
name_type String
|
93
|
+
payload_type Hash do
|
94
|
+
key 'sub_hash', Hash
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:json_payload) { {sub_hash: {key:'value'}}.to_json }
|
100
|
+
let(:body) { StringIO.new("--boundary\r\nContent-Disposition: form-data; name=blah\r\n\r\n#{json_payload}\r\n--boundary--") }
|
101
|
+
let(:content_type) { "multipart/form-data; boundary=boundary" }
|
102
|
+
|
103
|
+
it do
|
104
|
+
expect(payload.part('blah').payload['sub_hash']).to eq('key' => 'value')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context '.describe' do
|
109
|
+
subject(:description) { type.describe(false) }
|
110
|
+
|
111
|
+
its([:name]) { should eq 'Praxis::Types::MultipartArray' }
|
112
|
+
|
113
|
+
it { should have_key :part_name }
|
114
|
+
it { should have_key :attributes }
|
115
|
+
it { should have_key :pattern_attributes }
|
116
|
+
|
117
|
+
context 'attributes' do
|
118
|
+
subject(:attributes) { description[:attributes] }
|
119
|
+
its(:keys) { should match_array ['title', 'files', 'image']}
|
120
|
+
|
121
|
+
context 'the "title" part' do
|
122
|
+
subject(:title_description) { attributes['title'] }
|
123
|
+
|
124
|
+
it 'describes the options' do
|
125
|
+
expect(title_description[:options][:required]).to be true
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'describes the payload' do
|
129
|
+
expect(title_description[:type][:payload][:type]).to eq Attributor::String.describe
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'the "files" part' do
|
134
|
+
subject(:files_description) { attributes['files'] }
|
135
|
+
|
136
|
+
it 'describes the options' do
|
137
|
+
expect(files_description[:options][:multiple]).to be true
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'describes the payload' do
|
141
|
+
expect(files_description[:type][:payload][:type]).to eq Attributor::Tempfile.describe
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'describes the filename' do
|
145
|
+
filename = files_description[:type][:filename]
|
146
|
+
expect(filename[:options]).to eq(regexp: /file/)
|
147
|
+
expect(filename[:type]).to eq Attributor::String.describe
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'pattern attributes' do
|
154
|
+
subject(:pattern_attributes) { description[:pattern_attributes] }
|
155
|
+
its(:keys) { should match_array ['nam', 'stuff']}
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with no parts defined' do
|
159
|
+
let(:type) do
|
160
|
+
Class.new(Praxis::Types::MultipartArray) do
|
161
|
+
name_type DateTime
|
162
|
+
payload_type Hash
|
163
|
+
end
|
164
|
+
end
|
165
|
+
its([:name]) { should eq 'Praxis::Types::MultipartArray' }
|
166
|
+
|
167
|
+
it { should_not have_key :attributes }
|
168
|
+
it { should_not have_key :pattern_attributes }
|
169
|
+
|
170
|
+
it { should have_key :part_name }
|
171
|
+
it { should have_key :part_payload }
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'with an example passed in' do
|
175
|
+
let(:example) { type.example }
|
176
|
+
subject(:description) { type.describe(false, example: example) }
|
177
|
+
|
178
|
+
it 'uses the example values' do
|
179
|
+
expect(
|
180
|
+
description[:attributes]['title'][:type][:payload][:example]
|
181
|
+
).to eq example.part('title').payload
|
182
|
+
|
183
|
+
file_example = example.part('files').first.payload
|
184
|
+
file_example.rewind
|
185
|
+
expect(
|
186
|
+
description[:attributes]['files'][:type][:payload][:example]
|
187
|
+
).to eq file_example.read
|
188
|
+
|
189
|
+
image_example = example.part('image').payload
|
190
|
+
image_example.rewind
|
191
|
+
expect(
|
192
|
+
description[:attributes]['image'][:type][:payload][:example]
|
193
|
+
).to eq image_example.read
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'dumping' do
|
199
|
+
subject(:dumped) { payload.dump }
|
200
|
+
|
201
|
+
it 'dumps' do
|
202
|
+
loaded = type.load(dumped, content_type: payload.content_type)
|
203
|
+
end
|
204
|
+
context 'an example' do
|
205
|
+
let(:payload) { type.example }
|
206
|
+
|
207
|
+
it 'dumps' do
|
208
|
+
loaded = type.load(dumped, content_type: payload.content_type)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'with errors' do
|
214
|
+
let(:form) do
|
215
|
+
form_data = MIME::Multipart::FormData.new
|
216
|
+
|
217
|
+
entity = MIME::Text.new('James')
|
218
|
+
form_data.add entity,'name'
|
219
|
+
|
220
|
+
|
221
|
+
entity = MIME::Text.new('file1')
|
222
|
+
form_data.add entity,'files', 'file1'
|
223
|
+
|
224
|
+
form_data
|
225
|
+
end
|
226
|
+
|
227
|
+
subject(:errors) { payload.validate }
|
228
|
+
|
229
|
+
it 'validates part headers' do
|
230
|
+
expect(errors).to have(3).items
|
231
|
+
expect(errors).to match_array([
|
232
|
+
%r|\.name\.payload value .* does not match regexp|,
|
233
|
+
%r|\.files\.headers.* is not within the allowed values|,
|
234
|
+
%r|\.title is required|
|
235
|
+
])
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context '.example' do
|
240
|
+
subject(:payload) { type.example }
|
241
|
+
|
242
|
+
it 'generates parts' do
|
243
|
+
title = payload.part('title')
|
244
|
+
expect(title).to_not be_nil
|
245
|
+
expect(title.payload).to match /\w+/
|
246
|
+
|
247
|
+
files = payload.part('files')
|
248
|
+
expect(files).to have(2).items
|
249
|
+
|
250
|
+
files.each do |file|
|
251
|
+
expect(file.payload).to be_kind_of(Tempfile)
|
252
|
+
expect(file.filename).to match /\w+/
|
253
|
+
|
254
|
+
expect(file.headers['Content-Type']).to eq 'application/octet-stream'
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'is valid' do
|
259
|
+
expect(payload.validate).to have(0).items
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'with a hackish default part definition' do
|
265
|
+
let(:type) do
|
266
|
+
Class.new(Praxis::Types::MultipartArray) do
|
267
|
+
self.options[:case_insensitive_load] = true
|
268
|
+
|
269
|
+
part /\d+/, Instance
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
let(:form) do
|
274
|
+
form_data = MIME::Multipart::FormData.new
|
275
|
+
|
276
|
+
(1..5).each do |i|
|
277
|
+
instance = Instance.example("instance-#{i}")
|
278
|
+
body = JSON.pretty_generate(instance.render)
|
279
|
+
entity = MIME::Text.new(body)
|
280
|
+
form_data.add entity,i.to_s
|
281
|
+
end
|
282
|
+
|
283
|
+
form_data
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'loads the parts as the proper type' do
|
287
|
+
payload.each do |part|
|
288
|
+
expect(part.payload).to be_kind_of(Instance)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
context 'anonymous generation' do
|
296
|
+
let(:definition_block) do
|
297
|
+
proc do
|
298
|
+
name_type Integer
|
299
|
+
payload_type Instance
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
let(:attribute) do
|
304
|
+
Attributor::Attribute.new(Praxis::Types::MultipartArray, &definition_block)
|
305
|
+
end
|
306
|
+
|
307
|
+
let(:form) do
|
308
|
+
form_data = MIME::Multipart::FormData.new
|
309
|
+
|
310
|
+
(1..5).each do |i|
|
311
|
+
instance = Instance.example("instance-#{i}")
|
312
|
+
body = JSON.pretty_generate(instance.render)
|
313
|
+
entity = MIME::Text.new(body)
|
314
|
+
form_data.add entity,i.to_s
|
315
|
+
end
|
316
|
+
|
317
|
+
form_data
|
318
|
+
end
|
319
|
+
|
320
|
+
let(:payload) { attribute.load(body, content_type: content_type) }
|
321
|
+
|
322
|
+
it 'loads the parts as the proper type' do
|
323
|
+
expect(payload).to have(5).items
|
324
|
+
payload.each do |part|
|
325
|
+
expect(part.name).to be_kind_of(Integer)
|
326
|
+
expect(part.payload).to be_kind_of(Instance)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
end
|