twinfieldrb 0.3.0

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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/codeql-analysis.yml +70 -0
  3. data/.github/workflows/rspec.yml +33 -0
  4. data/.gitignore +6 -0
  5. data/.rspec +1 -0
  6. data/CHANGELOG.md +15 -0
  7. data/Gemfile +4 -0
  8. data/README.md +120 -0
  9. data/Rakefile +1 -0
  10. data/lib/twinfield/abstract_model.rb +7 -0
  11. data/lib/twinfield/api/base_api.rb +50 -0
  12. data/lib/twinfield/api/finder.rb +45 -0
  13. data/lib/twinfield/api/o_auth_session.rb +58 -0
  14. data/lib/twinfield/api/process.rb +44 -0
  15. data/lib/twinfield/api/session.rb +170 -0
  16. data/lib/twinfield/browse/transaction/cost_center.rb +145 -0
  17. data/lib/twinfield/browse/transaction/customer.rb +413 -0
  18. data/lib/twinfield/browse/transaction/general_ledger.rb +144 -0
  19. data/lib/twinfield/configuration.rb +49 -0
  20. data/lib/twinfield/create/cost_center.rb +39 -0
  21. data/lib/twinfield/create/creditor.rb +88 -0
  22. data/lib/twinfield/create/debtor.rb +88 -0
  23. data/lib/twinfield/create/error.rb +30 -0
  24. data/lib/twinfield/create/general_ledger.rb +39 -0
  25. data/lib/twinfield/create/transaction.rb +97 -0
  26. data/lib/twinfield/customer.rb +612 -0
  27. data/lib/twinfield/helpers/parsers.rb +23 -0
  28. data/lib/twinfield/helpers/transaction_match.rb +40 -0
  29. data/lib/twinfield/request/find.rb +149 -0
  30. data/lib/twinfield/request/list.rb +66 -0
  31. data/lib/twinfield/request/read.rb +111 -0
  32. data/lib/twinfield/sales_invoice.rb +409 -0
  33. data/lib/twinfield/transaction.rb +112 -0
  34. data/lib/twinfield/version.rb +5 -0
  35. data/lib/twinfield.rb +89 -0
  36. data/script/boot.rb +58 -0
  37. data/script/console +2 -0
  38. data/spec/fixtures/cluster/finder/ivt.xml +1 -0
  39. data/spec/fixtures/cluster/processxml/columns/sales_transactions.xml +312 -0
  40. data/spec/fixtures/cluster/processxml/customer/create_success.xml +100 -0
  41. data/spec/fixtures/cluster/processxml/customer/read_success.xml +93 -0
  42. data/spec/fixtures/cluster/processxml/customer/update_success.xml +1 -0
  43. data/spec/fixtures/cluster/processxml/invoice/create_error.xml +8 -0
  44. data/spec/fixtures/cluster/processxml/invoice/create_final_error.xml +67 -0
  45. data/spec/fixtures/cluster/processxml/invoice/create_success.xml +64 -0
  46. data/spec/fixtures/cluster/processxml/invoice/read_not_found.xml +1 -0
  47. data/spec/fixtures/cluster/processxml/invoice/read_success.xml +106 -0
  48. data/spec/fixtures/cluster/processxml/read/deb.xml +12 -0
  49. data/spec/fixtures/cluster/processxml/response.xml +8 -0
  50. data/spec/fixtures/login/session/wsdl.xml +210 -0
  51. data/spec/spec_helper.rb +17 -0
  52. data/spec/stubs/finder_stubs.rb +19 -0
  53. data/spec/stubs/processxml_stubs.rb +41 -0
  54. data/spec/stubs/session_stubs.rb +28 -0
  55. data/spec/twinfield/api/oauth_session_spec.rb +37 -0
  56. data/spec/twinfield/api/process_spec.rb +7 -0
  57. data/spec/twinfield/browse/transaction/cost_center_spec.rb +60 -0
  58. data/spec/twinfield/browse/transaction/general_ledger_spec.rb +60 -0
  59. data/spec/twinfield/browse/transaction/transaction_spec.rb +72 -0
  60. data/spec/twinfield/config_spec.rb +60 -0
  61. data/spec/twinfield/customer_spec.rb +326 -0
  62. data/spec/twinfield/request/find_spec.rb +24 -0
  63. data/spec/twinfield/request/list_spec.rb +58 -0
  64. data/spec/twinfield/request/read_spec.rb +26 -0
  65. data/spec/twinfield/sales_invoice_spec.rb +253 -0
  66. data/spec/twinfield/session_spec.rb +77 -0
  67. data/spec/twinfield/transaction_spec.rb +149 -0
  68. data/twinfieldrb.gemspec +24 -0
  69. data/wsdls/accounting/finder.wsdl +157 -0
  70. data/wsdls/accounting/process.wsdl +199 -0
  71. data/wsdls/accounting/session.wsdl +452 -0
  72. data/wsdls/accounting2/finder.wsdl +157 -0
  73. data/wsdls/accounting2/process.wsdl +199 -0
  74. data/wsdls/api.accounting/finder.wsdl +157 -0
  75. data/wsdls/api.accounting/process.wsdl +199 -0
  76. data/wsdls/session.wsdl +210 -0
  77. data/wsdls/update +10 -0
  78. metadata +196 -0
@@ -0,0 +1,19 @@
1
+ module FinderStubs
2
+ def stub_finder type, oauth: false
3
+ stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
4
+ .with(
5
+ body: /<Search xmlns="http:\/\/www.twinfield.com\/"><type>#{type}<\/type><pattern>\*<\/pattern><field>0<\/field><firstRow>1<\/firstRow><maxRows>100<\/maxRows><options><\/options><\/Search>/,
6
+ headers: {
7
+ "Soapaction" => '"http://www.twinfield.com/Search"'
8
+ }
9
+ )
10
+ .to_return(status: 200, body: File.read(File.expand_path("../../fixtures/cluster/finder/#{type.downcase}.xml", __FILE__)), headers: {})
11
+ end
12
+
13
+ private
14
+
15
+ def twinfield_header(oauth, company = nil)
16
+ company_fragment = company ? "<CompanyCode>#{company}</CompanyCode>" : ""
17
+ oauth ? "<Header xmlns=\"http://www.twinfield.com/\"><AccessToken>2b128baa05dd3cabc61e534435884961</AccessToken>#{company_fragment}</Header>" : "<Header xmlns=\"http://www.twinfield.com/\"><SessionID>session_id</SessionID></Header>"
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ module ProcessxmlStubs
2
+ def stub_processxml_list_dimensions dimension_type: "DEB", company: "company", oauth: false
3
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
4
+ .with(
5
+ body: /<soap:Body><ProcessXmlString xmlns="http:\/\/www.twinfield.com\/"><xmlRequest><!\[CDATA\[\n <list>\n <type>dimensions<\/type>\n <dimtype>#{dimension_type}<\/dimtype>\n<office>#{company}<\/office>\n <\/list>\n \]\]><\/xmlRequest><\/ProcessXmlString><\/soap:Body>/,
6
+ headers: {
7
+ "Soapaction" => '"http://www.twinfield.com/ProcessXmlString"'
8
+ }
9
+ )
10
+ .to_return(status: 200, body: File.read(File.expand_path("../../fixtures/cluster/processxml/response.xml", __FILE__)), headers: {})
11
+ end
12
+
13
+ def stub_processxml_list_offices oauth: false, company: nil
14
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
15
+ .with(
16
+ body: /<soap:Body><ProcessXmlString xmlns="http:\/\/www.twinfield.com\/"><xmlRequest><!\[CDATA\[\n <list>\n <type>offices<\/type>\n \n <\/list>\n \]\]><\/xmlRequest><\/ProcessXmlString><\/soap:Body>/,
17
+ headers: {
18
+ "Soapaction" => '"http://www.twinfield.com/ProcessXmlString"'
19
+ }
20
+ )
21
+ .to_return(status: 200, body: File.read(File.expand_path("../../fixtures/cluster/processxml/response.xml", __FILE__)), headers: {})
22
+ end
23
+
24
+ def stub_processxml_read_dimensions dimtype, oauth: false, company: nil
25
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
26
+ .with(
27
+ body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soap:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.twinfield.com/\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Header>#{twinfield_header(oauth, company)}</soap:Header><soap:Body><ProcessXmlString xmlns=\"http://www.twinfield.com/\"><xmlRequest><![CDATA[\n <read>\n <type>dimensions</type>\n <dimtype>#{dimtype}</dimtype>\n </read>\n ]]></xmlRequest></ProcessXmlString></soap:Body></soap:Envelope>",
28
+ headers: {
29
+ "Soapaction" => '"http://www.twinfield.com/ProcessXmlString"'
30
+ }
31
+ )
32
+ .to_return(status: 200, body: File.read(File.expand_path("../../fixtures/cluster/processxml/read/#{dimtype.downcase}.xml", __FILE__)), headers: {})
33
+ end
34
+
35
+ private
36
+
37
+ def twinfield_header(oauth, company = nil)
38
+ company_fragment = company ? "<CompanyCode>#{company}</CompanyCode>" : ""
39
+ oauth ? "<Header xmlns=\"http://www.twinfield.com/\"><AccessToken>2b128baa05dd3cabc61e534435884961</AccessToken>#{company_fragment}</Header>" : "<Header xmlns=\"http://www.twinfield.com/\"><SessionID>session_id</SessionID></Header>"
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ module SessionStubs
2
+ def stub_create_session username: "username", password: "password", organisation: "organisation", response: "Ok"
3
+ stub_request(:post, "https://login.twinfield.com/webservices/session.asmx")
4
+ .with(
5
+ body: /<tns:user>#{username}<\/tns:user><tns:password>#{password}<\/tns:password><tns:organisation>#{organisation}<\/tns:organisation><\/tns:Logon>/,
6
+ headers: {
7
+ Soapaction: '"http://www.twinfield.com/Logon"'
8
+
9
+ }
10
+ ).to_return(status: 200, body: "<env:Envelope><env:Header><Header><SessionId>session_id</SessionId></Header></env:Header><env:Body><LogonResponse><LogonResult>#{response}</LogonResult><Cluster>https://accounting.twinfield.com</Cluster></LogonResponse></env:Body></env:Envelope>")
11
+ end
12
+
13
+ def stub_cluster_session_wsdl
14
+ stub_request(:get, "https://accounting.twinfield.com/webservices/session.asmx?wsdl")
15
+ .to_return(status: 200, body: File.read(File.expand_path("../../../wsdls/accounting/session.wsdl", __FILE__)))
16
+ end
17
+
18
+ def stub_select_company company: "company"
19
+ stub_request(:post, "https://accounting.twinfield.com/webservices/session.asmx")
20
+ .with(
21
+ body: /<soap:Body><SelectCompany xmlns="http:\/\/www.twinfield.com\/"><company>#{company}<\/company><\/SelectCompany><\/soap:Body>/,
22
+ headers: {
23
+ "Soapaction" => '"http://www.twinfield.com/SelectCompany"'
24
+ }
25
+ )
26
+ .to_return(status: 200, body: "", headers: {})
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Api::OAuthSession do
4
+ include SessionStubs
5
+
6
+ context "OAuth configured" do
7
+ before do
8
+ Twinfield.configure do |config|
9
+ config.session_type = "Twinfield::Api::OAuthSession"
10
+ config.cluster = "https://accounting.twinfield.com"
11
+ config.access_token = "2b128baa05dd3cabc61e534435884961"
12
+ end
13
+ end
14
+
15
+ after do
16
+ Twinfield.configure do |config|
17
+ config.session_type = nil
18
+ config.cluster = nil
19
+ config.access_token = nil
20
+ end
21
+ end
22
+
23
+ it "returns true when oauth is configured" do
24
+ session = Twinfield::Api::OAuthSession.new
25
+
26
+ expect(session.connected?).to be_truthy
27
+ end
28
+ end
29
+
30
+ describe "#connected?" do
31
+ it "returns false when no access token is supplied" do
32
+ session = Twinfield::Api::OAuthSession.new
33
+
34
+ expect(session.connected?).to be_falsey
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Api::Process do
4
+ it "...." do
5
+ # TODO
6
+ end
7
+ end
@@ -0,0 +1,60 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Browse::Transaction::CostCenter do
4
+ include SessionStubs
5
+ include FinderStubs
6
+ include ProcessxmlStubs
7
+
8
+ before do
9
+ stub_create_session
10
+ stub_cluster_session_wsdl
11
+ stub_select_company
12
+ end
13
+
14
+ describe "class methods" do
15
+ describe ".where" do
16
+ it "returns transactions" do
17
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
18
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
19
+
20
+ transaction = Twinfield::Browse::Transaction::CostCenter.where.first
21
+
22
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::CostCenter)
23
+ expect(transaction.value).to eql(2200.0)
24
+ end
25
+
26
+ it "accepts a customer code" do
27
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
28
+ .with(body: /<from>1000\/01<\/from>/)
29
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
30
+
31
+ transaction = Twinfield::Browse::Transaction::CostCenter.where(years: 1000..2000).first
32
+
33
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::CostCenter)
34
+ expect(transaction.value).to eql(2200.0)
35
+ end
36
+
37
+ it "accepts a customer code" do
38
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
39
+ .with(body: /<from>4040<\/from>\s*<to>4040<\/to>/)
40
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
41
+
42
+ transaction = Twinfield::Browse::Transaction::CostCenter.where(dim1: "4040").first
43
+
44
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::CostCenter)
45
+ expect(transaction.value).to eql(2200.0)
46
+ end
47
+
48
+ it "accepts a invoice number" do
49
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
50
+ .with(body: /abcd12002/)
51
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
52
+
53
+ transaction = Twinfield::Browse::Transaction::CostCenter.where(dim2: "abcd12002").first
54
+
55
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::CostCenter)
56
+ expect(transaction.value).to eql(2200.0)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,60 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Browse::Transaction::GeneralLedger do
4
+ include SessionStubs
5
+ include FinderStubs
6
+ include ProcessxmlStubs
7
+
8
+ before do
9
+ stub_create_session
10
+ stub_cluster_session_wsdl
11
+ stub_select_company
12
+ end
13
+
14
+ describe "class methods" do
15
+ describe ".where" do
16
+ it "returns transactions" do
17
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
18
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
19
+
20
+ transaction = Twinfield::Browse::Transaction::GeneralLedger.where.first
21
+
22
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::GeneralLedger)
23
+ expect(transaction.value).to eql(2200.0)
24
+ end
25
+
26
+ it "accepts a customer code" do
27
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
28
+ .with(body: /<from>1000\/01<\/from>/)
29
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
30
+
31
+ transaction = Twinfield::Browse::Transaction::GeneralLedger.where(years: 1000..2000).first
32
+
33
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::GeneralLedger)
34
+ expect(transaction.value).to eql(2200.0)
35
+ end
36
+
37
+ it "accepts a customer code" do
38
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
39
+ .with(body: /<from>4040<\/from>\s*<to>4040<\/to>/)
40
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
41
+
42
+ transaction = Twinfield::Browse::Transaction::GeneralLedger.where(dim1: "4040").first
43
+
44
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::GeneralLedger)
45
+ expect(transaction.value).to eql(2200.0)
46
+ end
47
+
48
+ it "accepts a invoice number" do
49
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
50
+ .with(body: /abcd12002/)
51
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
52
+
53
+ transaction = Twinfield::Browse::Transaction::GeneralLedger.where(dim2: "abcd12002").first
54
+
55
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::GeneralLedger)
56
+ expect(transaction.value).to eql(2200.0)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Browse::Transaction::Customer do
4
+ include SessionStubs
5
+ include FinderStubs
6
+ include ProcessxmlStubs
7
+
8
+ before do
9
+ stub_create_session
10
+ stub_cluster_session_wsdl
11
+ stub_select_company
12
+ end
13
+
14
+ describe "instance methods" do
15
+ describe "#to_transaction_match_line_xml" do
16
+ it "returns a valid piece of xml" do
17
+ xml = Nokogiri::XML(Twinfield::Browse::Transaction::Customer.new(code: "VRK", number: "20210120").to_transaction_match_line_xml(1))
18
+ xml.css("line transcode").text
19
+ xml.css("line transnumber").text
20
+ xml.css("line transline").text == "1"
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "class methods" do
26
+ describe ".where" do
27
+ it "returns transactions" do
28
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
29
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
30
+
31
+ transaction = Twinfield::Browse::Transaction::Customer.where.first
32
+
33
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
34
+ expect(transaction.value).to eql(2200.0)
35
+ end
36
+
37
+ it "accepts a customer code" do
38
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
39
+ .with(body: /abcd12002/)
40
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
41
+
42
+ transaction = Twinfield::Browse::Transaction::Customer.where(customer_code: "abcd12002").first
43
+
44
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
45
+ expect(transaction.value).to eql(2200.0)
46
+ expect(transaction.date).to eql(Date.new(2021, 12, 5))
47
+ end
48
+
49
+ it "accepts a customer code" do
50
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
51
+ .with(body: /abcd12002/)
52
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
53
+
54
+ transaction = Twinfield::Browse::Transaction::Customer.where(customer_code: "abcd12002").first
55
+
56
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
57
+ expect(transaction.value).to eql(2200.0)
58
+ end
59
+
60
+ it "accepts a invoice number" do
61
+ stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
62
+ .with(body: /abcd12002/)
63
+ .to_return(body: File.read(File.expand_path("../../../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
64
+
65
+ transaction = Twinfield::Browse::Transaction::Customer.where(invoice_number: "abcd12002").first
66
+
67
+ expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
68
+ expect(transaction.value).to eql(2200.0)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,60 @@
1
+ require "spec_helper"
2
+
3
+ describe Twinfield::Configuration do
4
+ after do
5
+ reset_config
6
+ end
7
+
8
+ it "configures username" do
9
+ Twinfield.configure do |config|
10
+ config.username = "my_username"
11
+ end
12
+ expect(Twinfield.configuration.username).to eq "my_username"
13
+ end
14
+
15
+ it "configures password" do
16
+ Twinfield.configure do |config|
17
+ config.password = "my_password"
18
+ end
19
+ expect(Twinfield.configuration.password).to eq "my_password"
20
+ end
21
+
22
+ it "configures organisation" do
23
+ Twinfield.configure do |config|
24
+ config.organisation = "my_organisation"
25
+ end
26
+ expect(Twinfield.configuration.organisation).to eq "my_organisation"
27
+ end
28
+
29
+ describe "#session_class" do
30
+ it "returns a session class" do
31
+ expect(Twinfield.configuration.session_class).to eq(Twinfield::Api::Session)
32
+ end
33
+
34
+ it "returns a oauth session class when configured" do
35
+ Twinfield.configure do |config|
36
+ config.session_type = "Twinfield::Api::OAuthSession"
37
+ end
38
+ expect(Twinfield.configuration.session_class).to eq(Twinfield::Api::OAuthSession)
39
+ Twinfield.configure do |config|
40
+ config.session_type = nil
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#access_token_expired?" do
46
+ it "raises when no access token is given" do
47
+ expect { Twinfield.configuration.access_token_expired? }.to raise_error(Twinfield::Configuration::Error)
48
+ end
49
+
50
+ it "returns expired on an old access token" do
51
+ Twinfield.configuration.access_token = "abc.#{Base64.encode64(JSON({exp: (Time.now - 100).to_i}))}.abc"
52
+ expect(Twinfield.configuration.access_token_expired?).to eq(true)
53
+ end
54
+
55
+ it "returns not expired on an old access token" do
56
+ Twinfield.configuration.access_token = "abc.#{Base64.encode64(JSON({exp: (Time.now + 100).to_i}))}.abc"
57
+ expect(Twinfield.configuration.access_token_expired?).to eq(false)
58
+ end
59
+ end
60
+ end