Class: SimMeterAU::Providers::AldiMobile

Inherits:
SimMeterAU::Provider show all
Defined in:
lib/sim_meter_au/providers/aldi_mobile.rb,
lib/sim_meter_au/providers/aldi_mobile/parsers/usage.rb,
lib/sim_meter_au/providers/aldi_mobile/parsers/orders.rb,
lib/sim_meter_au/providers/aldi_mobile/parsers/service_details.rb

Defined Under Namespace

Modules: Parsers

Constant Summary collapse

DEFAULT_BASE_URL =
"https://my.aldimobile.com.au"
LOGIN_PATH =
"/login/"
LOGIN_FORM_ACTION =
%r{/login_check/?\z}
SERVICE_SWITCH_PATH =
%r{\A/admin/s/(?<id>\d+)/switch/?\z}
MOBILE_NUMBER =
/(?:\+?61[\s-]?|0)4(?:[\s-]?\d){8}/

Constants inherited from SimMeterAU::Provider

SimMeterAU::Provider::OPERATIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from SimMeterAU::Provider

credential_names, credentials_from, display_name, #login!, #provider, provider_key

Constructor Details

#initialize(login:, password:, base_url: DEFAULT_BASE_URL, agent: nil) ⇒ AldiMobile

Returns a new instance of AldiMobile.

Raises:



22
23
24
25
26
27
28
29
30
31
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 22

def initialize(login:, password:, base_url: DEFAULT_BASE_URL, agent: nil)
  raise ConfigurationError, "login cannot be empty" if .to_s.strip.empty?
  raise ConfigurationError, "password cannot be empty" if password.to_s.empty?

  @login = .to_s
  @password = password.to_s
  @base_url = base_url.delete_suffix("/")
  @agent = agent || build_agent
  @authenticated = false
end

Instance Attribute Details

#pageObject (readonly)

Returns the value of attribute page.



20
21
22
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 20

def page
  @page
end

Instance Method Details

#authenticate!Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 33

def authenticate!
   = @agent.get("#{@base_url}#{LOGIN_PATH}")
  form = ()

  unless form
    raise UnexpectedResponseError, "ALDImobile login form was not found"
  end

  form["login_user[login]"] = @login
  form["login_user[password]"] = @password

  submit_button = form.button_with(name: "login_user[save]")
  @page = submit_button ? @agent.submit(form, submit_button) : form.submit

  unless authenticated_page?(@page)
    @authenticated = false
    raise AuthenticationError, authentication_error_message(@page)
  end

  @authenticated = true
  self
rescue Mechanize::ResponseCodeError => error
  raise ConnectionError, "ALDImobile returned HTTP #{error.response_code}"
rescue SocketError, Timeout::Error, EOFError, Errno::ECONNREFUSED,
  Errno::ECONNRESET, OpenSSL::SSL::SSLError => error
  raise ConnectionError, "Could not connect to ALDImobile: #{error.class}"
end

#authenticated?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 61

def authenticated?
  @authenticated
end

#orders(identifier) ⇒ Object



136
137
138
139
140
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 136

def orders(identifier)
  selected_service = service(identifier)
  page = request { @agent.get("#{@base_url}/admin/s/#{selected_service.id}/orders") }
  Parsers::Orders.new.parse(page)
end

#service(identifier) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 83

def service(identifier)
  ensure_authenticated!
  return identifier if identifier.is_a?(Service)

  query = identifier.to_s.strip
  matches = services.select do |candidate|
    candidate.id == query ||
      candidate.number == normalize_identifier_number(query) ||
      candidate.name.casecmp?(query)
  end

  if matches.empty?
    raise ServiceNotFoundError, "No ALDImobile service matches #{query.inspect}"
  end
  if matches.length > 1
    raise AmbiguousServiceError, "More than one ALDImobile service matches #{query.inspect}"
  end

  matches.first
end

#service_details(identifier) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 104

def service_details(identifier)
  selected_service = service(identifier)
  overview = request { @agent.get("#{@base_url}/admin/s/#{selected_service.id}/switch") }
  roaming_enabled = roaming_enabled?(selected_service)

  Parsers::ServiceDetails.new.parse(
    page: overview,
    service: selected_service,
    roaming_enabled:
  )
end

#servicesObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 65

def services
  ensure_authenticated!

  @page.links.filter_map do |link|
    match = SERVICE_SWITCH_PATH.match(link.href.to_s)
    next unless match

    number = link.text.to_s[MOBILE_NUMBER]
    next unless number

    Service.new(
      id: match[:id],
      name: service_name(link.text, number),
      number: normalize_mobile_number(number)
    )
  end.uniq(&:id)
end

#usage(identifier, from: Date.today - 30, to: Date.today) ⇒ Object

Raises:



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/sim_meter_au/providers/aldi_mobile.rb', line 116

def usage(identifier, from: Date.today - 30, to: Date.today)
  selected_service = service(identifier)
  from = coerce_date(from)
  to = coerce_date(to)
  raise ConfigurationError, "usage start date must not be after end date" if from > to

  page = request { @agent.get("#{@base_url}/admin/s/#{selected_service.id}/usage") }
  form = page.forms.find { |candidate| candidate.action.to_s.end_with?("/usage") }
  unless form
    raise UnexpectedResponseError, "ALDImobile usage form was not found"
  end

  form["usage[start]"] = from.iso8601
  form["usage[end]"] = to.iso8601
  submit_button = form.button_with(name: "usage[getusage]")
  result = request { submit_button ? @agent.submit(form, submit_button) : form.submit }

  Parsers::Usage.new.parse(page: result, service: selected_service, from:, to:)
end