From 9455066c8fdd763790661e4892aa578615c0d9d6 Mon Sep 17 00:00:00 2001 From: Steve Bertrand Date: Fri, 22 Apr 2022 09:24:01 -0700 Subject: [PATCH] Add tests for update_data_files() --- lib/Tesla/API.pm | 48 ++++++++++++---- t/925-update_data_files.t | 116 ++++++++++++++++++++++++++++++++++++++ t/TestSuite.pm | 17 ++++++ 3 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 t/925-update_data_files.t diff --git a/lib/Tesla/API.pm b/lib/Tesla/API.pm index e398e69..a59eeb1 100644 --- a/lib/Tesla/API.pm +++ b/lib/Tesla/API.pm @@ -39,8 +39,8 @@ use constant { API_CACHE_TIMEOUT_SECONDS => 2, API_TIMEOUT_RETRIES => 3, AUTH_CACHE_FILE => "$home_dir/tesla_auth_cache.json", - ENDPOINTS_FILE => dist_file('Tesla-API', 'endpoints.json'), - OPTION_CODES_FILE => dist_file('Tesla-API', 'option_codes.json'), + ENDPOINTS_FILE => $ENV{TESLA_API_ENDPOINTS_FILE} // dist_file('Tesla-API', 'endpoints.json'), + OPTION_CODES_FILE => $ENV{TESLA_API_OPTIONCODES_FILE} // dist_file('Tesla-API', 'option_codes.json'), TOKEN_EXPIRY_WINDOW => 5, URL_API => 'https://owner-api.teslamotors.com/', URL_ENDPOINTS => 'https://raw.githubusercontent.com/tdorssers/TeslaPy/master/teslapy/endpoints.json', @@ -163,8 +163,8 @@ sub api_cache_time { sub endpoints { my ($self, $endpoint) = @_; - if (! $self->{endpoints} || $self->{reset_data}) { - $self->{reset_data} = 0; + if (! $self->{endpoints} || $self->{reset_endpoints_data}) { + $self->{reset_endpoints_data} = 0; my $json_endpoints; { @@ -206,7 +206,10 @@ sub mech { sub option_codes { my ($self, $code) = @_; - if (! $self->{option_codes}) { + if (! $self->{option_codes} || $self->{reset_option_codes_data}) { + print "RESET DATA\n"; + $self->{reset_option_codes_data} = 0; + my $json_option_codes; { local $/; @@ -230,9 +233,19 @@ sub option_codes { return $self->{option_codes}; } sub update_data_files { - my ($self) = @_; + my ($self, $url_type) = @_; + + my @urls_to_process; + + if (defined $url_type) { + push @urls_to_process, URL_ENDPOINTS if $url_type eq 'endpoints'; + push @urls_to_process, URL_OPTION_CODES if $url_type eq 'option_codes'; + } + else { + @urls_to_process = (ENDPOINTS_FILE, OPTION_CODES_FILE); + } - for my $data_url (URL_ENDPOINTS, URL_OPTION_CODES) { + for my $data_url (@urls_to_process) { my $filename; if ($data_url =~ /.*\/(\w+\.json)$/) { @@ -275,8 +288,17 @@ sub update_data_files { } if ($data_differs) { - $self->{reset_data} = 1; - my $file = dist_file('Tesla-API', $filename); + + my $file = $filename =~ /endpoints/ + ? ENDPOINTS_FILE + : OPTION_CODES_FILE ; + + if ($filename =~ /endpoints/) { + $self->{reset_endpoints_data} = 1; + } + else { + $self->{reset_option_codes_data} = 1; + } # Make a backup copy @@ -1171,7 +1193,9 @@ file. I: C -I: None +I: C<$ENV{TESLA_API_ENDPOINTS_FILE}>. Note that this must be +configured within a C block, prior to the C line for it +to have effect. =head2 OPTION_CODES_FILE @@ -1180,7 +1204,9 @@ for Tesla products. I: C -I: None +I: C<$ENV{TESLA_API_OPTIONCODES_FILE}>. Note that this must be +configured within a C block, prior to the C line for it +to have effect. =head2 TOKEN_EXPIRY_WINDOW diff --git a/t/925-update_data_files.t b/t/925-update_data_files.t new file mode 100644 index 0000000..bab64ab --- /dev/null +++ b/t/925-update_data_files.t @@ -0,0 +1,116 @@ +use warnings; +use strict; + +use File::Copy; +use FindBin qw($RealBin); + +my $endpoints_file; +my $optcodes_file; + +BEGIN { + $endpoints_file = "$RealBin/test_data/endpoints_new.json"; + $optcodes_file = "$RealBin/test_data/optcodes_new.json"; + + for ($endpoints_file, $optcodes_file) { + open my $fh, '>', $_ or die $!; + print $fh "{}"; + } + + $ENV{TESLA_API_ENDPOINTS_FILE} = $endpoints_file; + $ENV{TESLA_API_OPTIONCODES_FILE} = $optcodes_file; +} + +use lib 't/'; + +use Data::Dumper; +use JSON; +use Mock::Sub; +use Tesla::API; +use Test::More; +use TestSuite; + +my $t = Tesla::API->new(unauthenticated => 1); +my $ts = TestSuite->new; +my $ms = Mock::Sub->new; + +my $endpoints = $ts->file_data('t/test_data/endpoints.json'); +my $optcodes = $ts->file_data('t/test_data/option_codes.json'); + +my $api_sub = $ms->mock('Tesla::API::_tesla_api_call'); + +for my $type ('endpoints', 'option_codes') { + is keys %{ $t->$type }, 0, "$type has no entries ok"; + + my $return = $type eq 'endpoints' + ? encode_json($endpoints) + : encode_json($optcodes); + + $api_sub->return_value( + 1, + 200, + $return + ); + + $t->update_data_files($type); + + my $api_endpoints = $t->endpoints; + my $api_options = $t->option_codes; + + + if ($type eq 'endpoints') { + is keys %{ $api_endpoints } > 0, 1, "Updated $type file has entries ok"; + + is + keys %$api_endpoints, + keys %$endpoints, + "endpoints() returns the proper number of endpoints ok"; + + for my $endpoint (keys %$endpoints) { + for (keys %{$endpoints->{$endpoint}}) { + is + $api_endpoints->{$endpoint}{$_}, + $endpoints->{$endpoint}{$_}, + "Attribute $_ for endpoint $endpoint is $endpoints->{$endpoint}{$_} ok"; + } + } + } + else { + is keys %{ $api_options } > 0, 1, "Updated $type file has entries ok"; + + is + keys %$api_options, + keys %$optcodes, + "option_codes() returns the proper number of option codes ok"; + + for my $option (keys %$optcodes) { + is + $api_options->{$option}, + $optcodes->{$option}, + "Value for option $option is correct"; + + is + $t->option_codes($option), + $optcodes->{$option}, + "Value for option $option is correct via option_codes($option)"; + } + } +} + +my $endpoints_end = $ts->file_data($endpoints_file); +my $optcodes_end = $ts->file_data($optcodes_file); + +is keys %{$endpoints_end} > 0, 1, "Updated endpoints file has entries ok"; +is keys %{$optcodes_end} > 0, 1, "Updated optcodes file has entries ok"; + +unlink $endpoints_file or die $!; +unlink $optcodes_file or die $!; + +my @files = glob 't/test_data/*.json.*'; + +is scalar @files, 2, "Proper number of file backups ok"; + +for (@files) { + unlink $_ or die !$; +} + +done_testing(); \ No newline at end of file diff --git a/t/TestSuite.pm b/t/TestSuite.pm index c0f6397..45bfb38 100644 --- a/t/TestSuite.pm +++ b/t/TestSuite.pm @@ -3,6 +3,7 @@ package TestSuite; use warnings; use strict; +use Carp qw(croak); use Data::Dumper; use JSON; @@ -23,6 +24,22 @@ sub data { return $perl; } +sub file_data { + my ($self, $filename) = @_; + + croak "Need filename as param" if ! defined $filename; + + my $perl; + + { + local $/; + open my $fh, '<', $filename or die $!; + my $json = <$fh>; + $perl = decode_json($json); + } + + return $perl; +} sub json { my ($self, $want) = @_;