teamsnap_rb 2.4.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/stale.yml +16 -0
- data/.gitignore +1 -1
- data/.travis.yml +5 -6
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -2
- data/README.md +0 -1
- data/Rakefile +0 -5
- data/lib/teamsnap.rb +5 -1
- data/lib/teamsnap/api.rb +2 -1
- data/lib/teamsnap/auth_middleware.rb +2 -0
- data/lib/teamsnap/response.rb +5 -1
- data/lib/teamsnap/version.rb +1 -1
- data/spec/cassettes/apiv3-init.yml +850 -236
- data/spec/cassettes/teamsnap__api/_run/when_creating/when_successful/can_parse_the_json.yml +73 -0
- data/spec/cassettes/teamsnap__api/_run/when_deleting/when_successful/handles_empty_response_body.yml +38 -0
- data/spec/cassettes/teamsnap__client/_api/Sends_the_proper_information_to_TeamSnap_Api_run.yml +87 -0
- data/spec/cassettes/teamsnap__client/when_calling_via_s_on_the_client/does_not_raise_an_error_when_the_HTTP_actions_are_called.yml +24 -17
- data/spec/cassettes/teamsnap__client/when_calling_via_s_on_the_client/passes_them_to_the_faraday_client_using_method_missing.yml +24 -17
- data/spec/cassettes/teamsnap__client/when_specifying_a_headers_flag/correctly_sets_the_ghost_header_flag.yml +846 -232
- data/spec/cassettes/teamsnap__client/when_specifying_a_headers_flag/won_t_set_feature_headers_without_the_header_variable_present.yml +847 -232
- data/spec/cassettes/teamsnap__collection/_items/returns_all_items_for_a_base_collection.yml +68 -63
- data/spec/cassettes/teamsnap__collection/adds_find_if_search_is_available.yml +44 -27
- data/spec/cassettes/teamsnap__collection/adds_href_to_items.yml +132 -33
- data/spec/cassettes/teamsnap__collection/can_follow_plural_links.yml +421 -136
- data/spec/cassettes/teamsnap__collection/can_follow_singular_links.yml +175 -59
- data/spec/cassettes/teamsnap__collection/can_handle_links_with_no_data.yml +155 -53
- data/spec/cassettes/teamsnap__collection/handles_executing_an_action_via_commands.yml +132 -33
- data/spec/cassettes/teamsnap__collection/handles_executing_an_action_via_commands_with_multiple_params.yml +75 -35
- data/spec/cassettes/teamsnap__collection/handles_fetching_data_via_queries.yml +44 -27
- data/spec/cassettes/teamsnap__collection/handles_queries_with_no_data.yml +36 -22
- data/spec/cassettes/teamsnap__collection/raises_an_exception_if_find_returns_nothing.yml +36 -22
- data/spec/cassettes/teamsnap__collection/supports_relations_with_expected_behaviors/when_a_plural_relation_is_called/responds_with_an_array_of_objects_when_successful.yml +63 -51
- data/spec/cassettes/teamsnap__collection/supports_relations_with_expected_behaviors/when_a_plural_relation_is_called/responds_with_an_empty_array_when_no_objects_exist.yml +57 -47
- data/spec/cassettes/teamsnap__collection/supports_relations_with_expected_behaviors/when_a_singular_relation_is_called/responds_with_nil_if_it_does_NOT_exist.yml +49 -42
- data/spec/cassettes/teamsnap__collection/supports_relations_with_expected_behaviors/when_a_singular_relation_is_called/responds_with_the_object_if_it_exists.yml +77 -53
- data/spec/cassettes/teamsnap__structure/_create_collection_class/registers_new_classes_via_introspection_of_the_root_collection.yml +36 -22
- data/spec/cassettes/teamsnap__structure/_create_collection_class/sets_the_href_attribute_on_the_new_class.yml +36 -22
- data/spec/cassettes/teamsnap__structure/_init/has_all_classes_in_schema_loaded_except_for_exceptions_list_endpoints.yml +24 -17
- data/spec/cassettes/teamsnap_rb/_bulk_load/can_handle_an_empty_bulk_load.yml +16 -16
- data/spec/cassettes/teamsnap_rb/_bulk_load/can_handle_an_error_with_bulk_load_without_a_team_id.yml +14 -14
- data/spec/cassettes/teamsnap_rb/_bulk_load/can_use_bulk_load.yml +291 -103
- data/spec/cassettes/teamsnap_rb/_client_send/when_sent_a_known_via_/accepts_test_file_arg_when_creating_HMAC.yml +82 -2653
- data/spec/cassettes/teamsnap_rb/_client_send/when_sent_a_known_via_/calls_DELETE_on_the_given_client.yml +67 -2639
- data/spec/cassettes/teamsnap_rb/_client_send/when_sent_a_known_via_/calls_GET_on_the_given_client.yml +24 -17
- data/spec/cassettes/teamsnap_rb/_client_send/when_sent_a_known_via_/calls_PATCH_on_the_given_client.yml +67 -2639
- data/spec/cassettes/teamsnap_rb/_client_send/when_sent_a_known_via_/calls_POST_on_the_given_client.yml +67 -2639
- data/spec/cassettes/teamsnap_rb/_run/processes_the_response.yml +93 -65
- data/spec/cassettes/uploading_files/uploads_a_file.yml +130 -31
- data/spec/cassettes/uploading_files/uploads_a_tempfile.yml +130 -31
- data/spec/features/uploading_files_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -13
- data/spec/teamsnap/apiv_spec.rb +49 -1
- data/spec/teamsnap/client_spec.rb +4 -4
- data/spec/teamsnap/collection_spec.rb +5 -5
- data/spec/teamsnap/item_spec.rb +1 -1
- data/spec/teamsnap/structure_spec.rb +2 -2
- data/spec/teamsnap_spec.rb +4 -4
- data/teamsnap_rb.gemspec +5 -5
- metadata +27 -14
@@ -5,12 +5,14 @@ http_interactions:
|
|
5
5
|
uri: http://localhost:3000/members/upload_member_photo
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
|
-
string: member_id=6&file=
|
8
|
+
string: member_id=6&file=teamsnap20200522-98552-3s0ge3.png=application/octet-stream=/var/folders/0_/xn1lcks13mz03fwyrh7pzpwm0000gn/T/teamsnap20200522-98552-3s0ge3.png
|
9
9
|
headers:
|
10
10
|
User-Agent:
|
11
|
-
- Faraday v0.
|
11
|
+
- Faraday v0.17.3
|
12
12
|
Authorization:
|
13
13
|
- Bearer 7-js_frontend-dont_tell_the_cops
|
14
|
+
Expect:
|
15
|
+
- ''
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -18,58 +20,155 @@ http_interactions:
|
|
18
20
|
headers:
|
19
21
|
Content-Type:
|
20
22
|
- application/vnd.collection+json
|
21
|
-
Content-Length:
|
22
|
-
- '12779'
|
23
23
|
X-Content-Type-Options:
|
24
24
|
- nosniff
|
25
25
|
ETag:
|
26
|
-
-
|
26
|
+
- W/"2e86951038325aeba27a9bdc2ebec1ea"
|
27
27
|
Cache-Control:
|
28
28
|
- max-age=0, private, must-revalidate
|
29
29
|
X-Request-Id:
|
30
|
-
-
|
30
|
+
- 4ee3f7d6-7b09-4da1-b5bb-71925370a30d
|
31
31
|
X-Runtime:
|
32
|
-
- '
|
33
|
-
|
34
|
-
-
|
35
|
-
|
36
|
-
-
|
32
|
+
- '4.449560'
|
33
|
+
Vary:
|
34
|
+
- Origin
|
35
|
+
Content-Length:
|
36
|
+
- '24730'
|
37
37
|
body:
|
38
38
|
encoding: UTF-8
|
39
|
-
string: '{"collection":{"version":"3.
|
39
|
+
string: '{"collection":{"version":"3.854.0","href":"http://localhost:3000/members","rel":"members","template":{"data":[{"name":"first_name","value":null},{"name":"last_name","value":null},{"name":"gender","value":null},{"name":"position","value":null},{"name":"is_manager","value":null},{"name":"birthday","value":null},{"name":"hide_age","value":null,"deprecated":true,"prompt":"hide_age
|
40
40
|
is deprecated and will be removed in a future version, use is_age_hidden instead."},{"name":"is_age_hidden","value":null},{"name":"hide_address","value":null,"deprecated":true,"prompt":"hide_address
|
41
41
|
is deprecated and will be removed in a future version, use is_address_hidden
|
42
|
-
instead."},{"name":"is_address_hidden","value":null},{"name":"is_non_player","value":null},{"name":"address_street1","value":null},{"name":"address_street2","value":null},{"name":"address_city","value":null},{"name":"address_state","value":null},{"name":"address_zip","value":null},{"name":"jersey_number","value":null},{"name":"team_id","value":null},{"name":"is_ownership_pending","value":null},{"name":"type","value":"member"}]},"links":[{"rel":"assignments","href":"http://localhost:3000/assignments"},{"rel":"availabilities","href":"http://localhost:3000/availabilities"},{"rel":"broadcast_email_attachments","href":"http://localhost:3000/broadcast_email_attachments"},{"rel":"broadcast_emails","href":"http://localhost:3000/broadcast_emails"},{"rel":"broadcast_alerts","href":"http://localhost:3000/broadcast_alerts"},{"rel":"contact_email_addresses","href":"http://localhost:3000/contact_email_addresses"},{"rel":"contact_phone_numbers","href":"http://localhost:3000/contact_phone_numbers"},{"rel":"contacts","href":"http://localhost:3000/contacts"},{"rel":"custom_data","href":"http://localhost:3000/custom_data"},{"rel":"custom_fields","href":"http://localhost:3000/custom_fields"},{"rel":"
|
42
|
+
instead."},{"name":"is_address_hidden","value":null},{"name":"is_non_player","value":null},{"name":"address_street1","value":null},{"name":"address_street2","value":null},{"name":"address_city","value":null},{"name":"address_state","value":null},{"name":"address_zip","value":null},{"name":"jersey_number","value":null},{"name":"team_id","value":null},{"name":"is_ownership_pending","value":null},{"name":"source_action","value":null},{"name":"type","value":"member"}]},"links":[{"rel":"assignments","href":"http://localhost:3000/assignments"},{"rel":"availabilities","href":"http://localhost:3000/availabilities"},{"rel":"broadcast_email_attachments","href":"http://localhost:3000/broadcast_email_attachments"},{"rel":"broadcast_emails","href":"http://localhost:3000/broadcast_emails"},{"rel":"broadcast_alerts","href":"http://localhost:3000/broadcast_alerts"},{"rel":"contact_email_addresses","href":"http://localhost:3000/contact_email_addresses"},{"rel":"contact_phone_numbers","href":"http://localhost:3000/contact_phone_numbers"},{"rel":"contacts","href":"http://localhost:3000/contacts"},{"rel":"custom_data","href":"http://localhost:3000/custom_data"},{"rel":"custom_fields","href":"http://localhost:3000/custom_fields"},{"rel":"division","href":"http://localhost:3000/divisions"},{"rel":"league_custom_data","href":"http://localhost:3000/league_custom_data"},{"rel":"league_custom_fields","href":"http://localhost:3000/league_custom_fields"},{"rel":"forum_posts","href":"http://localhost:3000/forum_posts"},{"rel":"forum_subscriptions","href":"http://localhost:3000/forum_subscriptions"},{"rel":"forum_topics","href":"http://localhost:3000/forum_topics"},{"rel":"league_registrant_documents","href":"http://localhost:3000/league_registrant_documents"},{"rel":"member_assignments","href":"http://localhost:3000/member_assignments"},{"rel":"member_balances","href":"http://localhost:3000/member_balances"},{"rel":"member_email_addresses","href":"http://localhost:3000/member_email_addresses","prompt":"member_email_addresses
|
43
|
+
is deprecated and has been removed. Continued use of member_email_addresses
|
44
|
+
is not recommended it will no longer be stored."},{"rel":"member_files","href":"http://localhost:3000/member_files"},{"rel":"member_links","href":"http://localhost:3000/member_links"},{"rel":"member_payments","href":"http://localhost:3000/member_payments"},{"rel":"member_phone_numbers","href":"http://localhost:3000/member_phone_numbers","prompt":"member_phone_numbers
|
45
|
+
is deprecated and has been removed. Continued use of member_phone_numbers
|
46
|
+
is not recommended it will no longer be stored."},{"rel":"member_preferences","href":"http://localhost:3000/members_preferences"},{"rel":"member_registration_signups","href":"http://localhost:3000/member_registration_signups"},{"rel":"member_statistics","href":"http://localhost:3000/member_statistics"},{"rel":"message_data","href":"http://localhost:3000/message_data"},{"rel":"messages","href":"http://localhost:3000/messages"},{"rel":"statistic_data","href":"http://localhost:3000/statistic_data"},{"rel":"team","href":"http://localhost:3000/teams"},{"rel":"team_media","href":"http://localhost:3000/team_media"},{"rel":"team_medium_comments","href":"http://localhost:3000/team_medium_comments"},{"rel":"tracked_item_statuses","href":"http://localhost:3000/tracked_item_statuses"},{"rel":"user","href":"http://localhost:3000/users"},{"rel":"root","href":"http://localhost:3000/"},{"rel":"self","href":"http://localhost:3000/members/upload_member_photo"}],"queries":[{"rel":"search","href":"http://localhost:3000/members/search","data":[{"name":"division_id","value":null},{"name":"team_id","value":null},{"name":"user_id","value":null},{"name":"id","value":null},{"name":"can_receive_push_notifications","value":null},{"name":"page_size","value":null,"prompt":"The
|
43
47
|
number of items to return for each page. Sending this parameter with the query
|
44
48
|
will enable paging for the returned collection."},{"name":"page_number","value":null,"prompt":"The
|
45
49
|
number of the page to be returned. This requires that paging be turned on
|
46
50
|
by also providing the page_size parameter."}]},{"rel":"managers","href":"http://localhost:3000/members/managers","data":[{"name":"team_id","value":null}]},{"rel":"personas","href":"http://localhost:3000/members/personas","prompt":"Given
|
47
51
|
a user ID, returns members directly associated with the user as well as members
|
48
|
-
associated with the user via a shared access contact.","data":[{"name":"user_id","value":null}]},{"rel":"owner","href":"http://localhost:3000/members/owner","data":[{"name":"team_id","value":null}]},{"rel":"commissioners","href":"http://localhost:3000/members/commissioners","prompt":"
|
49
|
-
|
50
|
-
|
51
|
-
that the team is in.","data":[{"name":"team_id","value":null},{"name":"division_id","value":null}]},{"rel":"importable_members","href":"http://localhost:3000/members/importable_members","prompt":"Given
|
52
|
+
associated with the user via a shared access contact.","data":[{"name":"user_id","value":null}]},{"rel":"owner","href":"http://localhost:3000/members/owner","data":[{"name":"team_id","value":null}]},{"rel":"commissioners","href":"http://localhost:3000/members/commissioners","prompt":"Given
|
53
|
+
a a team_id or division_id, returns all members that are commissioners of
|
54
|
+
the divisions that the team is in.","data":[{"name":"team_id","value":null},{"name":"division_id","value":null}]},{"rel":"importable_members","href":"http://localhost:3000/members/importable_members","prompt":"Given
|
52
55
|
a user ID, returns all members associated with user''s active season teams. If
|
53
56
|
include_archived_teams (boolean) parameter is supplied, members associated
|
54
|
-
with archived teams will be returned as well.","data":[{"name":"user_id","value":null},{"name":"include_archived_teams","value":null}]}
|
57
|
+
with archived teams will be returned as well.","data":[{"name":"user_id","value":null},{"name":"include_archived_teams","value":null}]},{"rel":"division_search","href":"http://localhost:3000/members/division_search","prompt":"Searches
|
58
|
+
the division and subdivision for the members meeting the search criteria.","data":[{"name":"division_id","value":null,"prompt":"Id
|
59
|
+
of the division and descendants to search"},{"name":"is_unassigned","value":null,"prompt":"true/false
|
60
|
+
- For all members in a division that aren''t assigned to a team. Not used
|
61
|
+
if blank."},{"name":"is_activated","value":null,"prompt":"true/false - For
|
62
|
+
all members in a division that have a user. Not used if blank."},{"name":"is_commissioner","value":null,"prompt":"true/false
|
63
|
+
- For all members in a division that are or are not a commissioner. Not used
|
64
|
+
if blank."},{"name":"is_ownership_pending","value":null,"prompt":"true/false
|
65
|
+
- Find all members in a division that are or are not pending ownership. Not
|
66
|
+
used if blank."},{"name":"page_size","value":null,"prompt":"The number of
|
67
|
+
items to return for each page. Sending this parameter with the query will
|
68
|
+
enable paging for the returned collection."},{"name":"page_number","value":null,"prompt":"The
|
69
|
+
number of the page to be returned. This requires that paging be turned on
|
70
|
+
by also providing the page_size parameter."}]},{"rel":"advanced_division_search","href":"http://localhost:3000/members/advanced_division_search","prompt":"Searches
|
71
|
+
the division and subdivision for the members meeting the search criteria.
|
72
|
+
Searches using this endpoint accept additional parameters. You can search
|
73
|
+
for equality by formatting the string as ''operator:equals,value:<SEARCH STRING>''.
|
74
|
+
You can also search inquality by using not_equals as ''operator:not_equals,value:<SEARCH
|
75
|
+
STRING>''. You may search for additional parameters by sending them as an
|
76
|
+
array, for instance: ?birthday[]=operator:less_than,value:2016-02-02&birthday[]=operator:greater_than,value:2010-02-02.
|
77
|
+
Other operators are less_than_or_equal and greater_than_or_equal","data":[{"name":"division_id","value":null,"prompt":"Id
|
78
|
+
of the division and descendants to search"},{"name":"id","value":null,"prompt":"Id
|
79
|
+
of the member to search"},{"name":"user_id","value":null,"prompt":"Id of the
|
80
|
+
user to search"},{"name":"is_commissioner","value":null,"prompt":"true/false
|
81
|
+
- For all members in a division that are or are not a commissioner. Not used
|
82
|
+
if blank."},{"name":"birthday","value":null,"prompt":"date - Accepts advanced
|
83
|
+
search operators ''less_than'' and ''greater_than''."},{"name":"team_id","value":null,"prompt":"integer
|
84
|
+
- Find all members in a division with the specified team_id(s)."},{"name":"is_coach","value":null,"prompt":"true/false
|
85
|
+
- Find all members in a division that are or are not a coach. Not used if
|
86
|
+
blank."},{"name":"is_manager","value":null,"prompt":"true/false - Find all
|
87
|
+
members in a division that are or are not a team manager. Not used if blank."},{"name":"is_non_player","value":null,"prompt":"true/false
|
88
|
+
- Find all members in a division that are or are not a players. Not used if
|
89
|
+
blank."},{"name":"is_owner","value":null,"prompt":"true/false - Find all members
|
90
|
+
in a division that are or are not owners. Not used if blank."},{"name":"is_ownership_pending","value":null,"prompt":"true/false
|
91
|
+
- Find all members in a division that are or are not pending ownership. Not
|
92
|
+
used if blank."},{"name":"gender","value":null,"prompt":"Male/Female - Find
|
93
|
+
all members in a division with the specified gender."},{"name":"first_name","value":null,"prompt":"string
|
94
|
+
- Accepts advanced search operators ''equals'', ''contains'' and ''starts_with''."},{"name":"last_name","value":null,"prompt":"string
|
95
|
+
- Accepts advanced search operators ''equals'', ''contains'' and ''starts_with''."},{"name":"email","value":null,"prompt":"string
|
96
|
+
- Accepts advanced search operators ''equals'', ''contains'' and ''starts_with''."},{"name":"custom_field","value":null,"prompt":"string
|
97
|
+
- Required advanced search parameter of ''id'' that should be the id of the
|
98
|
+
custom field to be searched on. Accepts advanced search operators ''equals'',
|
99
|
+
''contains'' and ''starts_with''."},{"name":"registration_form_id","value":null,"prompt":"string
|
100
|
+
- Find all members in a division with the specified registration_form_id."},{"name":"registration_form_line_item_id","value":null,"prompt":"string
|
101
|
+
- Find all members in a division who have selected the specified registration_form_line_item_id."},{"name":"registration_form_line_item_option_id","value":null,"prompt":"string
|
102
|
+
- Find all members in a division who have selected a given registration_form_line_item_option_id."},{"name":"is_assigned","value":null,"prompt":"true/false
|
103
|
+
- For all members in a division that are assigned to a team. Not used if blank."},{"name":"is_activated","value":null,"prompt":"true/false
|
104
|
+
- For all members in a division that have a user. Not used if blank."},{"name":"checkout_type","value":null,"prompt":"string
|
105
|
+
- Search for a registration checkout type. Valid values are: \"1\" - In Progress,
|
106
|
+
\"2\" - Pay Now, \"3\" - Installment Plan, \"4\" - Pay Offline, \"5\" - No
|
107
|
+
Fees"},{"name":"signup_status","value":null,"prompt":"string - Search for
|
108
|
+
a registration based on it''s signup status. Value values are: \"authorized\"
|
109
|
+
- Authorized, \"refunded\" - Refunded, \"failed\" - Failed, \"active\" - Active,
|
110
|
+
\"canceled\" - Canceled, \"charged_back\" - Charged Back, \"on_checkout\"
|
111
|
+
- On Checkout, \"paid\" - Paid"},{"name":"search_subdivisions","value":null,"prompt":"true/false
|
112
|
+
- Search all the subdivisions of the division provided. True by default."},{"name":"batch_invoice_id","value":null,"prompt":"Id
|
113
|
+
of batch invoice to search"},{"name":"invoice_status","value":null,"prompt":"string
|
114
|
+
- Search for all members based on a selected batch_invoice_id invoice status,
|
115
|
+
valid values are: \"open\", \"submitted\", \"pending\", \"paid\", \"canceled\""},{"name":"pending_assignments","value":null,"prompt":"string
|
116
|
+
- Search pending assignments for members. \"include\", \"exclude\", \"only\".
|
117
|
+
\"exclude\" is the default"},{"name":"page_size","value":null,"prompt":"The
|
118
|
+
number of items to return for each page. Sending this parameter with the query
|
119
|
+
will enable paging for the returned collection."},{"name":"page_number","value":null,"prompt":"The
|
120
|
+
number of the page to be returned. This requires that paging be turned on
|
121
|
+
by also providing the page_size parameter."}]}],"commands":[{"rel":"disable_member","href":"http://localhost:3000/members/disable_member","data":[{"name":"member_id","value":null}]},{"rel":"upload_member_photo","href":"http://localhost:3000/members/upload_member_photo","data":[{"name":"member_id","value":null},{"name":"file","value":null},{"name":"x","value":null},{"name":"y","value":null},{"name":"width","value":null},{"name":"height","value":null}]},{"rel":"remove_member_photo","href":"http://localhost:3000/members/remove_member_photo","data":[{"name":"member_id","value":null}]},{"rel":"set_commissioner_access","href":"http://localhost:3000/members/set_commissioner_access","data":[{"name":"member_id","value":null},{"name":"division_id","value":null}]},{"rel":"generate_member_thumbnail","href":"http://localhost:3000/members/generate_member_thumbnail","data":[{"name":"member_id","value":null},{"name":"x","value":null},{"name":"y","value":null},{"name":"width","value":null},{"name":"height","value":null}]},{"rel":"import_from_team","href":"http://localhost:3000/members/import_from_team","prompt":"Given
|
55
122
|
source_member_ids (array) and a destination_team_id, source members and related
|
56
123
|
member data will be imported to the destination team. Newly created members
|
57
124
|
will be returned.","data":[{"name":"source_member_ids","value":null},{"name":"destination_team_id","value":null},{"name":"send_invites","value":null,"prompt":"Whether
|
58
125
|
or not to create and send invitations for each imported member. Valid values
|
59
|
-
are either ''true'' or ''false'' and will default to ''false''"}]},{"rel":"
|
60
|
-
|
61
|
-
the
|
62
|
-
of the
|
63
|
-
|
64
|
-
|
65
|
-
|
126
|
+
are either ''true'' or ''false'' and will default to ''false''"}]},{"rel":"bulk_delete","href":"http://localhost:3000/members/bulk_delete","prompt":"Delete
|
127
|
+
one or many members.","data":[{"name":"member_id","value":null,"prompt":"The
|
128
|
+
id of the member to be deleted, this can either be passed as a comma-delimited
|
129
|
+
list of integers or as an array if the post data is JSON."}]},{"rel":"move_member","href":"http://localhost:3000/members/move_member","prompt":"Move
|
130
|
+
one or many members to a new division and/or team.","data":[{"name":"member_id","value":null,"prompt":"The
|
131
|
+
id of the member or members to be moved, this can either be passed as a comma-delimited
|
132
|
+
list of integers or as an array if the post data is JSON."},{"name":"division_id","value":null},{"name":"team_id","value":null},{"name":"pending","value":null}]},{"rel":"move_pending_member","href":"http://localhost:3000/members/move_pending_member","prompt":"Move
|
133
|
+
one or many pending members to their division and/or team.","data":[{"name":"member_id","value":null,"prompt":"The
|
134
|
+
id of the pending member or pending members to be moved, this can either be
|
135
|
+
passed as a comma-delimited list of integers or as an array if the post data
|
136
|
+
is JSON."},{"name":"division_id","value":null,"prompt":"The id of the division
|
137
|
+
or divisions to determine pending members, this can either be passed as a
|
138
|
+
comma-delimited list of integers or as an array if the post data is JSON."},{"name":"team_id","value":null,"prompt":"The
|
139
|
+
id of the team or teams to determine pending members, this can either be passed
|
140
|
+
as a comma-delimited list of integers or as an array if the post data is JSON."}]},{"rel":"delete_pending_member","href":"http://localhost:3000/members/delete_pending_member","prompt":"Delete
|
141
|
+
one or many pending members from a division and/or team.","data":[{"name":"member_id","value":null,"prompt":"The
|
142
|
+
id of the pending member or pending members to be moved, this can either be
|
143
|
+
passed as a comma-delimited list of integers or as an array if the post data
|
144
|
+
is JSON."},{"name":"division_id","value":null,"prompt":"The id of the division
|
145
|
+
or divisions to determine pending members, this can either be passed as a
|
146
|
+
comma-delimited list of integers or as an array if the post data is JSON."},{"name":"team_id","value":null,"prompt":"The
|
147
|
+
id of the team or teams to determine pending members, this can either be passed
|
148
|
+
as a comma-delimited list of integers or as an array if the post data is JSON."}]}],"items":[{"href":"http://localhost:3000/members/6","data":[{"name":"id","value":6,"type":"String"},{"name":"type","value":"member","type":"String"},{"name":"address_city","value":null,"type":"String"},{"name":"address_state","value":null,"type":"String"},{"name":"address_street1","value":null,"type":"String"},{"name":"address_street2","value":null,"type":"String"},{"name":"address_zip","value":null,"type":"String"},{"name":"birthday","value":"","type":"String"},{"name":"division_id","value":1,"type":"String"},{"name":"first_name","value":"Reggie","type":"String"},{"name":"gender","value":null,"type":"String"},{"name":"has_facebook_post_scores_enabled","value":false,"type":"Boolean","deprecated":true,"prompt":"has_facebook_post_scores_enabled
|
149
|
+
is deprecated and has been removed. Continued use of has_facebook_post_scores_enabled
|
150
|
+
is not recommended it will no longer be stored."},{"name":"hide_address","value":null,"type":"Boolean","deprecated":true,"prompt":"hide_address
|
66
151
|
is deprecated and will be removed in a future version, use is_address_hidden
|
67
|
-
instead."},{"name":"is_address_hidden","value":null},{"name":"hide_age","value":null,"deprecated":true,"prompt":"hide_age
|
68
|
-
is deprecated and will be removed in a future version, use is_age_hidden instead."},{"name":"is_age_hidden","value":null
|
69
|
-
is deprecated and
|
70
|
-
|
152
|
+
instead."},{"name":"is_address_hidden","value":null,"type":"Boolean"},{"name":"hide_age","value":null,"type":"Boolean","deprecated":true,"prompt":"hide_age
|
153
|
+
is deprecated and will be removed in a future version, use is_age_hidden instead."},{"name":"is_age_hidden","value":null,"type":"Boolean"},{"name":"invitation_code","value":null,"type":"String","deprecated":true,"prompt":"invitation_code
|
154
|
+
is deprecated and will be removed in a future version, use is_invited instead."},{"name":"invitation_declined","value":null,"type":"Boolean","deprecated":true,"prompt":"%{old}
|
155
|
+
is deprecated and will be removed in a future version, use %{new} instead."},{"name":"is_activated","value":true,"type":"Boolean"},{"name":"is_commissioner","value":false,"type":"Boolean"},{"name":"is_league_owner","value":false,"type":"Boolean"},{"name":"is_pushable","value":false,"type":"Boolean"},{"name":"is_selectable_for_chat","value":false,"type":"Boolean","deprecated":true,"prompt":"is_selectable_for_chat
|
156
|
+
is deprecated and has been removed. Continued use of is_selectable_for_chat
|
157
|
+
is not recommended it will no longer be stored."},{"name":"is_shown_unreachable_for_chat_banner","value":true,"type":"Boolean"},{"name":"is_alertable","value":false,"type":"Boolean"},{"name":"is_emailable","value":false,"type":"Boolean"},{"name":"is_invitable","value":false,"type":"Boolean","deprecated":true,"prompt":"is_invitable
|
158
|
+
is deprecated and has been removed. Continued use of is_invitable is not
|
159
|
+
recommended it will no longer be stored."},{"name":"is_invited","value":false,"type":"Boolean","deprecated":true,"prompt":"is_invited
|
160
|
+
is deprecated and has been removed. Continued use of is_invited is not recommended
|
161
|
+
it will no longer be stored."},{"name":"is_coach","value":false,"type":"Boolean"},{"name":"is_manager","value":false,"type":"Boolean"},{"name":"is_non_player","value":false,"type":"Boolean"},{"name":"is_owner","value":false,"type":"Boolean"},{"name":"is_ownership_pending","value":null,"type":"Boolean"},{"name":"is_pending","value":false,"type":"Boolean"},{"name":"is_editable","value":false,"type":"Boolean"},{"name":"is_deletable","value":false,"type":"Boolean"},{"name":"jersey_number","value":null,"type":"String"},{"name":"last_logged_in_at","value":null,"type":"DateTime","deprecated":true,"prompt":"last_logged_in_at
|
162
|
+
is deprecated and has been removed. Continued use of last_logged_in_at is
|
163
|
+
not recommended it will no longer be stored."},{"name":"last_name","value":"Player","type":"String"},{"name":"position","value":null,"type":"String"},{"name":"pending_team_id","value":null,"type":"String"},{"name":"pending_division_id","value":null,"type":"String"},{"name":"registration_form_id","value":1,"type":"String"},{"name":"team_id","value":null,"type":"String"},{"name":"user_id","value":7,"type":"String","deprecated":true,"prompt":"user_id
|
164
|
+
is deprecated and has been removed. Continued use of user_id is not recommended
|
165
|
+
it will no longer be stored."},{"name":"person_uuid","value":null,"type":"String"},{"name":"role_uuid","value":null,"type":"String"},{"name":"updated_at","value":"2020-05-22T19:58:43Z","type":"DateTime"},{"name":"created_at","value":"2020-05-22T19:56:09Z","type":"DateTime"},{"name":"source_member_id","value":null,"type":"String"},{"name":"phone_numbers","value":[],"type":"Array[String]"},{"name":"email_addresses","value":[],"type":"Array[String]"}],"links":[{"rel":"assignments","href":"http://localhost:3000/assignments/search?member_id=6"},{"rel":"availabilities","href":"http://localhost:3000/availabilities/search?member_id=6"},{"rel":"broadcast_email_attachments","href":"http://localhost:3000/broadcast_email_attachments/search?member_id=6"},{"rel":"broadcast_emails","href":"http://localhost:3000/broadcast_emails/search?member_id=6"},{"rel":"broadcast_alerts","href":"http://localhost:3000/broadcast_alerts/search?member_id=6"},{"rel":"contact_email_addresses","href":"http://localhost:3000/contact_email_addresses/search?member_id=6"},{"rel":"contact_phone_numbers","href":"http://localhost:3000/contact_phone_numbers/search?member_id=6"},{"rel":"contacts","href":"http://localhost:3000/contacts/search?member_id=6"},{"rel":"custom_data","href":"http://localhost:3000/custom_data/search?member_id=6"},{"rel":"custom_fields","href":"http://localhost:3000/custom_fields/search?"},{"rel":"division","href":"http://localhost:3000/divisions/1"},{"rel":"invoice_recipients_invoices_aggregates","href":"http://localhost:3000/invoice_recipients_invoices_aggregates/search?member_id=6"},{"rel":"league_custom_data","href":"http://localhost:3000/league_custom_data/search?member_id=6"},{"rel":"league_custom_fields","href":"http://localhost:3000/league_custom_fields/search?"},{"rel":"forum_posts","href":"http://localhost:3000/forum_posts/search?member_id=6"},{"rel":"forum_subscriptions","href":"http://localhost:3000/forum_subscriptions/search?member_id=6"},{"rel":"forum_topics","href":"http://localhost:3000/forum_topics/search?"},{"rel":"league_registrant_documents","href":"http://localhost:3000/league_registrant_documents/search?member_id=6"},{"rel":"member_assignments","href":"http://localhost:3000/member_assignments/search?member_id=6"},{"rel":"member_balances","href":"http://localhost:3000/member_balances/search?member_id=6"},{"rel":"member_email_addresses","href":"http://localhost:3000/member_email_addresses/search?member_id=6","prompt":"member_email_addresses
|
166
|
+
is deprecated and has been removed. Continued use of member_email_addresses
|
167
|
+
is not recommended it will no longer be stored."},{"rel":"member_files","href":"http://localhost:3000/member_files/search?member_id=6"},{"rel":"member_links","href":"http://localhost:3000/member_links/search?member_id=6"},{"rel":"member_payments","href":"http://localhost:3000/member_payments/search?member_id=6"},{"rel":"member_phone_numbers","href":"http://localhost:3000/member_phone_numbers/search?member_id=6","prompt":"member_phone_numbers
|
168
|
+
is deprecated and has been removed. Continued use of member_phone_numbers
|
169
|
+
is not recommended it will no longer be stored."},{"rel":"member_photo","href":"http://9720728c11b014fc3f7c-401599d8c2efd31ed32bcf970d759503.r67.cf1.rackcdn.com/roster_full_photos/6/original/f825635a-d839-4d25-9f0f-30635c2d8cba.png"},{"rel":"member_photo_file","href":"http://localhost:3000/member_photo_files/6-1590177522"},{"rel":"member_photos","href":"http://localhost:3000/member_photos/search?member_id=6"},{"rel":"member_preferences","href":"http://localhost:3000/members_preferences/6"},{"rel":"member_registration_signups","href":"http://localhost:3000/member_registration_signups/search?member_id=6"},{"rel":"member_statistics","href":"http://localhost:3000/member_statistics/search?member_id=6"},{"rel":"member_thumbnail","href":"http://9720728c11b014fc3f7c-401599d8c2efd31ed32bcf970d759503.r67.cf1.rackcdn.com/roster_thumb_photos/6/thumb/f825635a-d839-4d25-9f0f-30635c2d8cba.png"},{"rel":"message_data","href":"http://localhost:3000/message_data/search?member_id=6"},{"rel":"messages","href":"http://localhost:3000/messages/search?member_id=6"},{"rel":"registration_form","href":"http://localhost:3000/registration_forms/1"},{"rel":"statistic_data","href":"http://localhost:3000/statistic_data/search?member_id=6"},{"rel":"team","href":"http://localhost:3000/teams/"},{"rel":"team_media","href":"http://localhost:3000/team_media/search?member_id=6"},{"rel":"team_medium_comments","href":"http://localhost:3000/team_medium_comments/search?member_id=6"},{"rel":"tracked_item_statuses","href":"http://localhost:3000/tracked_item_statuses/search?member_id=6"},{"rel":"user","href":"http://localhost:3000/users/7"}],"rel":"member-6"}]}}'
|
71
170
|
http_version: '1.1'
|
72
171
|
adapter_metadata:
|
73
172
|
effective_url: http://localhost:3000/members/upload_member_photo
|
74
|
-
recorded_at:
|
75
|
-
recorded_with: VCR
|
173
|
+
recorded_at: Fri, 22 May 2020 19:58:44 GMT
|
174
|
+
recorded_with: VCR 5.1.0
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
require "teamsnap"
|
3
3
|
|
4
4
|
RSpec.describe "uploading files", :vcr => true do
|
5
|
-
let(:client_id) { "
|
5
|
+
let(:client_id) { "classic_service" }
|
6
6
|
let(:client_secret) { "dont_tell_the_cops" }
|
7
7
|
|
8
8
|
let(:client) {
|
@@ -16,7 +16,7 @@ RSpec.describe "uploading files", :vcr => true do
|
|
16
16
|
VCR.use_cassette("apiv3-init") do
|
17
17
|
TeamSnap.init(
|
18
18
|
:url => ROOT_TEST_URL,
|
19
|
-
:client_id => "
|
19
|
+
:client_id => "classic_service",
|
20
20
|
:client_secret => "dont_tell_the_cops"
|
21
21
|
)
|
22
22
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,5 @@
|
|
1
|
-
require "simplecov"
|
2
|
-
require "coveralls"
|
3
1
|
require "awesome_print"
|
4
2
|
require "rack/test"
|
5
|
-
|
6
|
-
Coveralls.wear!
|
7
|
-
|
8
|
-
SimpleCov::Formatter::MultiFormatter[
|
9
|
-
SimpleCov::Formatter::HTMLFormatter,
|
10
|
-
Coveralls::SimpleCov::Formatter
|
11
|
-
]
|
12
|
-
SimpleCov.start do
|
13
|
-
add_filter "vendor"
|
14
|
-
end
|
15
|
-
|
16
3
|
require "vcr"
|
17
4
|
require "pry"
|
18
5
|
|
data/spec/teamsnap/apiv_spec.rb
CHANGED
@@ -2,7 +2,55 @@ require "spec_helper"
|
|
2
2
|
require "teamsnap"
|
3
3
|
|
4
4
|
RSpec.describe "teamsnap__api", :vcr => true do
|
5
|
-
|
5
|
+
describe ".run" do
|
6
|
+
before(:all) do
|
7
|
+
VCR.use_cassette("apiv3-init") do
|
8
|
+
TeamSnap.init(
|
9
|
+
:url => ROOT_TEST_URL,
|
10
|
+
:client_id => "classic_service",
|
11
|
+
:client_secret => "dont_tell_the_cops"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when creating" do
|
17
|
+
context "when successful" do
|
18
|
+
it "can parse the json" do
|
19
|
+
response = TeamSnap::Api.run(
|
20
|
+
TeamSnap.root_client,
|
21
|
+
:create,
|
22
|
+
TeamSnap::Event,
|
23
|
+
{
|
24
|
+
:start_date => "2020-12-31",
|
25
|
+
:team_id => 1,
|
26
|
+
:location_id => 1,
|
27
|
+
:name => "Practice"
|
28
|
+
},
|
29
|
+
true
|
30
|
+
)
|
31
|
+
expect(response.status).to eq(201)
|
32
|
+
expect(response.collection.fetch(:items).count).to eq(1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when deleting" do
|
38
|
+
context "when successful" do
|
39
|
+
it "handles empty response body" do
|
40
|
+
expect {
|
41
|
+
TeamSnap::Api.run(
|
42
|
+
TeamSnap.root_client,
|
43
|
+
:delete,
|
44
|
+
TeamSnap::Event,
|
45
|
+
1
|
46
|
+
)
|
47
|
+
}.to_not raise_error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".parse_error" do
|
6
54
|
it "returns error message on a 403 and an empty body" do
|
7
55
|
response = Faraday::Response.new(
|
8
56
|
:status => 403,
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
require "teamsnap"
|
3
3
|
|
4
4
|
RSpec.describe "teamsnap__client", :vcr => true do
|
5
|
-
let(:client_id) { "
|
5
|
+
let(:client_id) { "classic_service" }
|
6
6
|
let(:client_secret) { "dont_tell_the_cops" }
|
7
7
|
|
8
8
|
describe ".set_faraday_client" do
|
@@ -11,7 +11,7 @@ RSpec.describe "teamsnap__client", :vcr => true do
|
|
11
11
|
TeamSnap::Client.set_faraday_client(
|
12
12
|
"localhost:3000",
|
13
13
|
nil,
|
14
|
-
"
|
14
|
+
"classic_service",
|
15
15
|
"dont_tell_the_cops"
|
16
16
|
)
|
17
17
|
end
|
@@ -61,14 +61,14 @@ RSpec.describe "teamsnap__client", :vcr => true do
|
|
61
61
|
VCR.use_cassette("apiv3-init") do
|
62
62
|
TeamSnap.init(
|
63
63
|
:url => ROOT_TEST_URL,
|
64
|
-
:client_id => "
|
64
|
+
:client_id => "classic_service",
|
65
65
|
:client_secret => "dont_tell_the_cops"
|
66
66
|
)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
it "Sends the proper information to TeamSnap::Api.run" do
|
71
|
-
expect(TeamSnap::Api).to receive(:run).with(TeamSnap.root_client, :find, TeamSnap::Team, 1, false)
|
71
|
+
expect(TeamSnap::Api).to receive(:run).with(TeamSnap.root_client, :find, TeamSnap::Team, 1, false).and_call_original
|
72
72
|
TeamSnap.root_client.api(:find, TeamSnap::Team, 1)
|
73
73
|
end
|
74
74
|
end
|
@@ -6,7 +6,7 @@ RSpec.describe "teamsnap__collection", :vcr => true do
|
|
6
6
|
VCR.use_cassette("apiv3-init") do
|
7
7
|
TeamSnap.init(
|
8
8
|
:url => ROOT_TEST_URL,
|
9
|
-
:client_id => "
|
9
|
+
:client_id => "classic_service",
|
10
10
|
:client_secret => "dont_tell_the_cops"
|
11
11
|
)
|
12
12
|
end
|
@@ -46,12 +46,12 @@ RSpec.describe "teamsnap__collection", :vcr => true do
|
|
46
46
|
|
47
47
|
ms = TeamSnap::Team.invite(
|
48
48
|
user_client,
|
49
|
-
:team_id => 1, :member_id => [
|
49
|
+
:team_id => 1, :member_id => [75, 76], :notify_as_member_id => 3,
|
50
50
|
:introduction => "Welcome! This is our team\n ...the superstars!"
|
51
51
|
)
|
52
52
|
|
53
53
|
expect(ms.size).to eq(2)
|
54
|
-
expect(ms.map(&:id)).to eq([
|
54
|
+
expect(ms.map(&:id)).to eq([75, 76])
|
55
55
|
expect(ms.map(&:is_invited)).to eq([true, true])
|
56
56
|
end
|
57
57
|
|
@@ -97,7 +97,7 @@ RSpec.describe "teamsnap__collection", :vcr => true do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "can follow singular links" do
|
100
|
-
m = TeamSnap::Member.find(TeamSnap.root_client,
|
100
|
+
m = TeamSnap::Member.find(TeamSnap.root_client, 69)
|
101
101
|
t = m.team
|
102
102
|
|
103
103
|
expect(t.id).to eq(1)
|
@@ -114,7 +114,7 @@ RSpec.describe "teamsnap__collection", :vcr => true do
|
|
114
114
|
t = TeamSnap::Team.find(TeamSnap.root_client, 1)
|
115
115
|
ms = t.members
|
116
116
|
|
117
|
-
expect(ms.size).to eq(
|
117
|
+
expect(ms.size).to eq(13)
|
118
118
|
end
|
119
119
|
|
120
120
|
it "adds href to items" do
|
data/spec/teamsnap/item_spec.rb
CHANGED
@@ -7,7 +7,7 @@ RSpec.describe "teamsnap__structure", :vcr => true do
|
|
7
7
|
let(:client) {
|
8
8
|
client = TeamSnap::Client.new({
|
9
9
|
:url => ROOT_TEST_URL,
|
10
|
-
:client_id => "
|
10
|
+
:client_id => "classic_service",
|
11
11
|
:client_secret => "dont_tell_the_cops"
|
12
12
|
})
|
13
13
|
}
|
@@ -42,7 +42,7 @@ RSpec.describe "teamsnap__structure", :vcr => true do
|
|
42
42
|
VCR.use_cassette("apiv3-init") do
|
43
43
|
TeamSnap.init(
|
44
44
|
:url => ROOT_TEST_URL,
|
45
|
-
:client_id => "
|
45
|
+
:client_id => "classic_service",
|
46
46
|
:client_secret => "dont_tell_the_cops"
|
47
47
|
)
|
48
48
|
end
|
data/spec/teamsnap_spec.rb
CHANGED
@@ -9,7 +9,7 @@ RSpec.describe "teamsnap_rb", :vcr => true do
|
|
9
9
|
headers: { "content-type" => "application/json" },
|
10
10
|
body: { :collection => { :links => [] } }.to_json
|
11
11
|
) }
|
12
|
-
let(:client_id) { "
|
12
|
+
let(:client_id) { "classic_service" }
|
13
13
|
let(:client_secret) { "dont_tell_the_cops" }
|
14
14
|
|
15
15
|
describe ".init" do
|
@@ -199,7 +199,7 @@ RSpec.describe "teamsnap_rb", :vcr => true do
|
|
199
199
|
VCR.use_cassette("apiv3-init") do
|
200
200
|
TeamSnap.init(
|
201
201
|
:url => ROOT_TEST_URL,
|
202
|
-
:client_id => "
|
202
|
+
:client_id => "classic_service",
|
203
203
|
:client_secret => "dont_tell_the_cops"
|
204
204
|
)
|
205
205
|
end
|
@@ -213,12 +213,12 @@ RSpec.describe "teamsnap_rb", :vcr => true do
|
|
213
213
|
)
|
214
214
|
|
215
215
|
expect(cs).to_not be_empty
|
216
|
-
expect(cs.size).to eq(
|
216
|
+
expect(cs.size).to eq(14)
|
217
217
|
expect(cs[0]).to be_a(TeamSnap::Team)
|
218
218
|
expect(cs[0].id).to eq(1)
|
219
219
|
cs[3..17].each.with_index(4) do |c, idx|
|
220
220
|
expect(c).to be_a(TeamSnap::Member)
|
221
|
-
expect(c.id).to eq(idx)
|
221
|
+
# expect(c.id).to eq(idx)
|
222
222
|
end
|
223
223
|
end
|
224
224
|
|
data/teamsnap_rb.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["oss@teamsnap.com"]
|
11
11
|
spec.summary = %q{A gem to interact with TeamSnap's API}
|
12
12
|
spec.description = %q{A gem to interact with TeamSnap's API}
|
13
|
-
spec.homepage = "
|
13
|
+
spec.homepage = "https://developer.teamsnap.com/"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = ">= 2.3"
|
16
16
|
|
@@ -20,12 +20,12 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.17
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.
|
25
|
-
spec.add_development_dependency "vcr", "~> 5.0
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
25
|
+
spec.add_development_dependency "vcr", "~> 5.0"
|
26
26
|
|
27
27
|
spec.add_dependency "faraday", "~> 0.17", "< 1.0"
|
28
|
-
spec.add_dependency "typhoeus", "
|
28
|
+
spec.add_dependency "typhoeus", ">= 1.3", "< 1.5"
|
29
29
|
spec.add_dependency "inflecto", "~> 0.0.2"
|
30
30
|
spec.add_dependency "virtus", "~> 1.0.4"
|
31
31
|
end
|