Class: Precheck::RuleProcessor

Inherits:
Object
  • Object
show all
Defined in:
precheck/lib/precheck/rule_processor.rb

Class Method Summary collapse

Class Method Details

.add_new_result_to_rule_hash(rule_hash: nil, result: nil) ⇒ Object

hash will be { rule: [result, result, result] }


119
120
121
122
123
124
125
126
# File 'precheck/lib/precheck/rule_processor.rb', line 119

def self.add_new_result_to_rule_hash(rule_hash: nil, result: nil)
  unless rule_hash.include?(result.rule)
    rule_hash[result.rule] = []
  end
  rule_results = rule_hash[result.rule]
  rule_results << result
  return rule_hash
end

.collect_iap_language_items(purchase_edit_versions: nil, is_optional: false) ⇒ Object


198
199
200
201
202
203
204
205
206
207
# File 'precheck/lib/precheck/rule_processor.rb', line 198

def self.collect_iap_language_items(purchase_edit_versions: nil, is_optional: false)
  items = []
  purchase_edit_versions.each do |language_key, hash|
    name = hash[:name]
    description = hash[:description]
    items << TextItemToCheck.new(name, :in_app_purchase, "in-app purchase name: #{name}: (#{language_key})", is_optional)
    items << TextItemToCheck.new(description, :in_app_purchase, "in-app purchase desc: #{description}: (#{language_key})", is_optional)
  end
  return items
end

.collect_text_items_from_language_item(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false) ⇒ Object

a few attributes are LanguageItem this method creates a TextItemToCheck for each pair


210
211
212
213
214
215
216
# File 'precheck/lib/precheck/rule_processor.rb', line 210

def self.collect_text_items_from_language_item(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false)
  items = []
  hash.each do |key, value|
    items << TextItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})", is_optional)
  end
  return items
end

.collect_urls_from_hash(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false) ⇒ Object


145
146
147
148
149
150
151
# File 'precheck/lib/precheck/rule_processor.rb', line 145

def self.collect_urls_from_hash(hash: nil, item_name: nil, friendly_name_postfix: nil, is_optional: false)
  items = []
  hash.each do |key, value|
    items << URLItemToCheck.new(value, item_name, "#{friendly_name_postfix}: (#{key})", is_optional)
  end
  return items
end

.generate_text_items_to_check(app: nil, app_version: nil) ⇒ Object


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'precheck/lib/precheck/rule_processor.rb', line 153

def self.generate_text_items_to_check(app: nil, app_version: nil)
  items = []

  items << TextItemToCheck.new(app_version.copyright, :copyright, "copyright")

  items += collect_text_items_from_language_item(hash: app_version.keywords,
                                            item_name: :keywords,
                                friendly_name_postfix: "keywords")

  items += collect_text_items_from_language_item(hash: app_version.description,
                                            item_name: :description,
                                friendly_name_postfix: "description")

  items += collect_text_items_from_language_item(hash: app_version.release_notes,
                                            item_name: :release_notes,
                                friendly_name_postfix: "release notes")

  items += collect_text_items_from_language_item(hash: app.details.name,
                                            item_name: :app_name,
                                friendly_name_postfix: "app name")

  items += collect_text_items_from_language_item(hash: app.details.apple_tv_privacy_policy,
                                            item_name: :app_subtitle,
                                friendly_name_postfix: " tv privacy policy")

  items += collect_text_items_from_language_item(hash: app.details.subtitle,
                                            item_name: :app_subtitle,
                                friendly_name_postfix: "app name subtitle",
                                          is_optional: true)

  should_include_iap = Precheck.config[:include_in_app_purchases]
  if should_include_iap
    UI.message("Reading in-app purchases. If you have a lot, this might take a while")
    UI.message("You can disable IAP checking by setting the `include_in_app_purchases` flag to `false`")
    in_app_purchases = app.in_app_purchases.all
    in_app_purchases ||= []
    in_app_purchases.each do |purchase|
      items += collect_iap_language_items(purchase_edit_versions: purchase.edit.versions)
    end
    UI.message("Done reading in-app purchases")
  end

  return items
end

.generate_url_items_to_check(app: nil, app_version: nil) ⇒ Object


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'precheck/lib/precheck/rule_processor.rb', line 128

def self.generate_url_items_to_check(app: nil, app_version: nil)
  items = []
  items += collect_urls_from_hash(hash: app_version.support_url,
                             item_name: :support_url,
                 friendly_name_postfix: "support URL")
  items += collect_urls_from_hash(hash: app_version.marketing_url,
                             item_name: :marketing_url,
                 friendly_name_postfix: "marketing URL",
                           is_optional: true)

  items += collect_urls_from_hash(hash: app.details.privacy_url,
                             item_name: :privacy_url,
                 friendly_name_postfix: "privacy URL",
                           is_optional: true)
  return items
end

.process_app_and_version(app: nil, app_version: nil, rules: nil) ⇒ Object


44
45
46
47
48
49
50
# File 'precheck/lib/precheck/rule_processor.rb', line 44

def self.process_app_and_version(app: nil, app_version: nil, rules: nil)
  items_to_check = []
  items_to_check += generate_text_items_to_check(app: app, app_version: app_version)
  items_to_check += generate_url_items_to_check(app: app, app_version: app_version)

  return process_rules(items_to_check: items_to_check, rules: rules)
end

.process_rules(items_to_check: nil, rules: nil) ⇒ Object


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'precheck/lib/precheck/rule_processor.rb', line 52

def self.process_rules(items_to_check: nil, rules: nil)
  items_not_checked = items_to_check.to_set # items we haven't checked by at least one rule
  error_results = {} # rule to fields map
  warning_results = {} # rule to fields map
  skipped_rules = []

  rules.each do |rule|
    rule_config = Precheck.config[rule.key]
    rule_level = rule_config[:level].to_sym unless rule_config.nil?
    rule_level ||= Precheck.config[:default_rule_level].to_sym

    if rule_level == RULE_LEVELS[:skip]
      skipped_rules << rule
      UI.message("Skipped: #{rule.class.friendly_name}-> #{rule.description}".yellow)
      next
    end

    if rule.needs_customization?
      if rule_config.nil? || rule_config[:data].nil?
        UI.verbose("#{rule.key} excluded because no data was passed to it e.g.: #{rule.key}(data: <data here>)")
        next
      end

      custom_data = rule_config[:data]
      rule.customize_with_data(data: custom_data)
    end

    # if the rule failed at least once, we won't print a success message
    rule_failed_at_least_once = false

    items_to_check.each do |item|
      result = rule.check_item(item)

      # each rule will determine if it can handle this item, if not, it will just pass nil back
      next if result.nil?

      # we've checked this item, remove it from list of items not checked
      items_not_checked.delete(item)

      # if we passed, then go to the next item, otherwise, recode the failure
      next unless result.status == VALIDATION_STATES[:failed]
      error_results = add_new_result_to_rule_hash(rule_hash: error_results, result: result) if rule_level == RULE_LEVELS[:error]
      warning_results = add_new_result_to_rule_hash(rule_hash: warning_results, result: result) if rule_level == RULE_LEVELS[:warn]
      rule_failed_at_least_once = true
    end

    if rule_failed_at_least_once
      message = "😵  Failed: #{rule.class.friendly_name}-> #{rule.description}"
      if rule_level == RULE_LEVELS[:error]
        UI.error(message)
      else
        UI.important(message)
      end
    else
      UI.message("✅  Passed: #{rule.class.friendly_name}")
    end
  end

  return RuleProcessResult.new(
    error_results: error_results,
    warning_results: warning_results,
    skipped_rules: skipped_rules,
    items_not_checked: items_not_checked.to_a
  )
end