Validate nodeinfo response by schema (#21395)
* add json-schema to :test in Gemfile * Create node_info_2.0_schema.json * test match_response_schema * Create match_response_schema.rb * Update nodeinfo_controller_spec.rb * Rename spec/support/node_info_2.0_schema.json to spec/support/schema/node_info_2.0_schema.json * Update match_response_schema.rb * cleanup * additionally validate the json schema itself disable throwing errors test the schema matcher * rename nodeinfo schema to nodeinfo_2.0 * use Rails.root.join to construct the path * prettify json * sync Gemfile.lock
This commit is contained in:
		
							parent
							
								
									f239d31f23
								
							
						
					
					
						commit
						6cdbc345f4
					
				
					 5 changed files with 184 additions and 2 deletions
				
			
		
							
								
								
									
										5
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Gemfile
									
									
									
									
									
								
							|  | @ -117,13 +117,14 @@ group :test do | |||
|   gem 'capybara', '~> 3.38' | ||||
|   gem 'climate_control', '~> 0.2' | ||||
|   gem 'faker', '~> 3.0' | ||||
|   gem 'json-schema', '~> 3.0' | ||||
|   gem 'microformats', '~> 4.4' | ||||
|   gem 'rack-test', '~> 2.0'   | ||||
|   gem 'rails-controller-testing', '~> 1.0' | ||||
|   gem 'rspec_junit_formatter', '~> 0.6' | ||||
|   gem 'rspec-sidekiq', '~> 3.1' | ||||
|   gem 'simplecov', '~> 0.21', require: false | ||||
|   gem 'webmock', '~> 3.18' | ||||
|   gem 'rspec_junit_formatter', '~> 0.6' | ||||
|   gem 'rack-test', '~> 2.0' | ||||
| end | ||||
| 
 | ||||
| group :development do | ||||
|  |  | |||
|  | @ -344,6 +344,8 @@ GEM | |||
|     json-ld-preloaded (3.2.2) | ||||
|       json-ld (~> 3.2) | ||||
|       rdf (~> 3.2) | ||||
|     json-schema (3.0.0) | ||||
|       addressable (>= 2.8) | ||||
|     jsonapi-renderer (0.2.2) | ||||
|     jwt (2.4.1) | ||||
|     kaminari (1.2.2) | ||||
|  | @ -791,6 +793,7 @@ DEPENDENCIES | |||
|   idn-ruby | ||||
|   json-ld | ||||
|   json-ld-preloaded (~> 3.2) | ||||
|   json-schema (~> 3.0) | ||||
|   kaminari (~> 1.2) | ||||
|   kt-paperclip (~> 7.1) | ||||
|   letter_opener (~> 1.8) | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ describe WellKnown::NodeInfoController, type: :controller do | |||
| 
 | ||||
|       json = body_as_json | ||||
| 
 | ||||
|       expect({ "foo" => 0 }).not_to match_json_schema("nodeinfo_2.0") | ||||
|       expect(json).to match_json_schema("nodeinfo_2.0") | ||||
|       expect(json[:version]).to eq '2.0' | ||||
|       expect(json[:usage]).to be_a Hash | ||||
|       expect(json[:software]).to be_a Hash | ||||
|  |  | |||
							
								
								
									
										6
									
								
								spec/support/matchers/json/match_json_schema.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								spec/support/matchers/json/match_json_schema.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| RSpec::Matchers.define :match_json_schema do |schema| | ||||
|   match do |input_json| | ||||
|     schema_path = Rails.root.join('spec', 'support', 'schema', "#{schema}.json").to_s | ||||
|     JSON::Validator.validate(schema_path, input_json, validate_schema: true) | ||||
|   end | ||||
| end | ||||
							
								
								
									
										170
									
								
								spec/support/schema/nodeinfo_2.0.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								spec/support/schema/nodeinfo_2.0.json
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,170 @@ | |||
| { | ||||
|   "$schema": "http://json-schema.org/draft-04/schema#", | ||||
|   "id": "http://nodeinfo.diaspora.software/ns/schema/2.0#", | ||||
|   "description": "NodeInfo schema version 2.0.", | ||||
|   "type": "object", | ||||
|   "additionalProperties": false, | ||||
|   "required": [ | ||||
|     "version", | ||||
|     "software", | ||||
|     "protocols", | ||||
|     "services", | ||||
|     "openRegistrations", | ||||
|     "usage", | ||||
|     "metadata" | ||||
|   ], | ||||
|   "properties": { | ||||
|     "version": { | ||||
|       "description": "The schema version, must be 2.0.", | ||||
|       "enum": ["2.0"] | ||||
|     }, | ||||
|     "software": { | ||||
|       "description": "Metadata about server software in use.", | ||||
|       "type": "object", | ||||
|       "additionalProperties": false, | ||||
|       "required": ["name", "version"], | ||||
|       "properties": { | ||||
|         "name": { | ||||
|           "description": "The canonical name of this server software.", | ||||
|           "type": "string", | ||||
|           "pattern": "^[a-z0-9-]+$" | ||||
|         }, | ||||
|         "version": { | ||||
|           "description": "The version of this server software.", | ||||
|           "type": "string" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "protocols": { | ||||
|       "description": "The protocols supported on this server.", | ||||
|       "type": "array", | ||||
|       "minItems": 1, | ||||
|       "items": { | ||||
|         "enum": [ | ||||
|           "activitypub", | ||||
|           "buddycloud", | ||||
|           "dfrn", | ||||
|           "diaspora", | ||||
|           "libertree", | ||||
|           "ostatus", | ||||
|           "pumpio", | ||||
|           "tent", | ||||
|           "xmpp", | ||||
|           "zot" | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     "services": { | ||||
|       "description": "The third party sites this server can connect to via their application API.", | ||||
|       "type": "object", | ||||
|       "additionalProperties": false, | ||||
|       "required": ["inbound", "outbound"], | ||||
|       "properties": { | ||||
|         "inbound": { | ||||
|           "description": "The third party sites this server can retrieve messages from for combined display with regular traffic.", | ||||
|           "type": "array", | ||||
|           "minItems": 0, | ||||
|           "items": { | ||||
|             "enum": [ | ||||
|               "atom1.0", | ||||
|               "gnusocial", | ||||
|               "imap", | ||||
|               "pnut", | ||||
|               "pop3", | ||||
|               "pumpio", | ||||
|               "rss2.0", | ||||
|               "twitter" | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         "outbound": { | ||||
|           "description": "The third party sites this server can publish messages to on the behalf of a user.", | ||||
|           "type": "array", | ||||
|           "minItems": 0, | ||||
|           "items": { | ||||
|             "enum": [ | ||||
|               "atom1.0", | ||||
|               "blogger", | ||||
|               "buddycloud", | ||||
|               "diaspora", | ||||
|               "dreamwidth", | ||||
|               "drupal", | ||||
|               "facebook", | ||||
|               "friendica", | ||||
|               "gnusocial", | ||||
|               "google", | ||||
|               "insanejournal", | ||||
|               "libertree", | ||||
|               "linkedin", | ||||
|               "livejournal", | ||||
|               "mediagoblin", | ||||
|               "myspace", | ||||
|               "pinterest", | ||||
|               "pnut", | ||||
|               "posterous", | ||||
|               "pumpio", | ||||
|               "redmatrix", | ||||
|               "rss2.0", | ||||
|               "smtp", | ||||
|               "tent", | ||||
|               "tumblr", | ||||
|               "twitter", | ||||
|               "wordpress", | ||||
|               "xmpp" | ||||
|             ] | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "openRegistrations": { | ||||
|       "description": "Whether this server allows open self-registration.", | ||||
|       "type": "boolean" | ||||
|     }, | ||||
|     "usage": { | ||||
|       "description": "Usage statistics for this server.", | ||||
|       "type": "object", | ||||
|       "additionalProperties": false, | ||||
|       "required": ["users"], | ||||
|       "properties": { | ||||
|         "users": { | ||||
|           "description": "statistics about the users of this server.", | ||||
|           "type": "object", | ||||
|           "additionalProperties": false, | ||||
|           "properties": { | ||||
|             "total": { | ||||
|               "description": "The total amount of on this server registered users.", | ||||
|               "type": "integer", | ||||
|               "minimum": 0 | ||||
|             }, | ||||
|             "activeHalfyear": { | ||||
|               "description": "The amount of users that signed in at least once in the last 180 days.", | ||||
|               "type": "integer", | ||||
|               "minimum": 0 | ||||
|             }, | ||||
|             "activeMonth": { | ||||
|               "description": "The amount of users that signed in at least once in the last 30 days.", | ||||
|               "type": "integer", | ||||
|               "minimum": 0 | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "localPosts": { | ||||
|           "description": "The amount of posts that were made by users that are registered on this server.", | ||||
|           "type": "integer", | ||||
|           "minimum": 0 | ||||
|         }, | ||||
|         "localComments": { | ||||
|           "description": "The amount of comments that were made by users that are registered on this server.", | ||||
|           "type": "integer", | ||||
|           "minimum": 0 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "metadata": { | ||||
|       "description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.", | ||||
|       "type": "object", | ||||
|       "minProperties": 0, | ||||
|       "additionalProperties": true | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Loading…
	
		Reference in a new issue