Skip to content

Commit b28c1f0

Browse files
committed
Fix Unit Tests (specs) and add some more
1 parent 0e801e1 commit b28c1f0

File tree

1 file changed

+124
-52
lines changed

1 file changed

+124
-52
lines changed
Lines changed: 124 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,159 @@
11
require 'spec_helper'
22

33
describe Fastlane::Actions::AndroidGenerateApkFromAabAction do
4-
before do
5-
allow(File).to receive(:file?).with(aab_file_path).and_return('mocked file data')
6-
allow(File).to receive(:file?).with(apk_output_file_path).and_return('mocked file data')
7-
allow(File).to receive(:file?).with(keystore_path).and_return('mocked file data')
8-
end
9-
10-
let(:aab_file_path) { 'path/to/app.aab' }
11-
let(:apk_output_file_path) { 'path/to/app.apk' }
12-
let(:keystore_path) { 'path/to/keystore' }
13-
let(:keystore_password) { 'keystore_password' }
14-
let(:keystore_key_alias) { 'keystore_key_alias' }
15-
let(:signing_key_password) { 'signing_key_password' }
4+
let(:aab_file_path) { 'Dev/My App/my-app.aab' }
5+
let(:apk_output_file_path) { 'Dev/My App/build/artifacts/my-universal-app.apk' }
166

17-
def generate_command(apk_output_file_path:, aab_file_path: nil, keystore_path: nil, keystore_password: nil, keystore_key_alias: nil, signing_key_password: nil)
18-
command = "bundletool build-apks --mode universal --bundle #{aab_file_path} --output-format DIRECTORY --output #{apk_output_file_path} "
19-
code_sign_arguments = "--ks #{keystore_path} --ks-pass #{keystore_password} --ks-key-alias #{keystore_key_alias} --key-pass #{signing_key_password} "
20-
move_and_cleanup_command = "&& mv #{apk_output_file_path}/universal.apk #{apk_output_file_path}_tmp && rm -rf #{apk_output_file_path} && mv #{apk_output_file_path}_tmp #{apk_output_file_path}"
7+
def expect_bundletool_call(aab, apk, *options)
8+
expect(Fastlane::Action).to receive('sh').with('command', '-v', 'bundletool', { print_command: false, print_command_output: false })
9+
allow(File).to receive(:file?).with(aab).and_return(true)
10+
expect(Fastlane::Action).to receive('sh').with(
11+
'bundletool', 'build-apks', '--mode', 'universal', '--bundle', aab,
12+
'--output-format', 'DIRECTORY', '--output', anything,
13+
*options
14+
)
15+
expect(FileUtils).to receive(:mkdir_p).with(File.dirname(apk))
16+
expect(FileUtils).to receive(:mv).with(anything, apk)
17+
end
2118

22-
# Append the code signing arguments
23-
command += code_sign_arguments unless keystore_path.nil?
19+
context 'when generating a signed APK' do
20+
let(:keystore_path) { 'Dev/My App/secrets/path/to/keystore' }
21+
let(:keystore_password) { 'keystore_password' }
22+
let(:keystore_key_alias) { 'keystore_key_alias' }
23+
let(:signing_key_password) { 'signing_key_password' }
2424

25-
# Append the move and cleanup command
26-
command += move_and_cleanup_command
27-
return command
28-
end
25+
it 'calls the `bundletool` command with the correct arguments' do
26+
allow(File).to receive(:file?).with(keystore_path).and_return(true)
27+
expect_bundletool_call(
28+
aab_file_path, apk_output_file_path,
29+
'--ks', keystore_path, '--ks-pass', keystore_password, '--ks-key-alias', keystore_key_alias, '--key-pass', signing_key_password
30+
)
2931

30-
describe 'android_generate_apk_from_aab' do
31-
it 'calls the `bundletool` command with the correct arguments when generating a signed APK' do
32-
cmd = run_described_fastlane_action(
32+
output = run_described_fastlane_action(
3333
aab_file_path: aab_file_path,
3434
apk_output_file_path: apk_output_file_path,
3535
keystore_path: keystore_path,
3636
keystore_password: keystore_password,
3737
keystore_key_alias: keystore_key_alias,
3838
signing_key_password: signing_key_password
3939
)
40-
expected_command = generate_command(aab_file_path: aab_file_path,
41-
apk_output_file_path: apk_output_file_path,
42-
keystore_path: keystore_path,
43-
keystore_password: keystore_password,
44-
keystore_key_alias: keystore_key_alias,
45-
signing_key_password: signing_key_password)
46-
expect(cmd).to eq(expected_command)
40+
41+
expect(output).to eq(apk_output_file_path)
4742
end
43+
end
4844

49-
it 'calls the `bundletool` command with the correct arguments when generating an unsigned APK' do
50-
cmd = run_described_fastlane_action(
45+
context 'when generating an unsigned APK' do
46+
it 'calls the `bundletool` command with the correct arguments' do
47+
expect_bundletool_call(aab_file_path, apk_output_file_path)
48+
49+
output = run_described_fastlane_action(
5150
aab_file_path: aab_file_path,
5251
apk_output_file_path: apk_output_file_path
5352
)
54-
expected_command = generate_command(aab_file_path: aab_file_path,
55-
apk_output_file_path: apk_output_file_path)
56-
expect(cmd).to eq(expected_command)
57-
end
5853

59-
it 'calls the `bundletool` command with the correct arguments and use the path to the AAB from the lane context if the SharedValues::GRADLE_AAB_OUTPUT_PATH key is set' do
60-
aab_path_from_context = 'path/from/context/app.aab'
54+
expect(output).to eq(apk_output_file_path)
55+
end
56+
end
6157

58+
describe 'parameter inference' do
59+
it 'infers the AAB path from lane context if `SharedValues::GRADLE_AAB_OUTPUT_PATH` is set' do
60+
aab_path_from_context = 'path/from/context/my-app.aab'
6261
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_AAB_OUTPUT_PATH] = aab_path_from_context
6362

64-
cmd = run_described_fastlane_action(
63+
expect_bundletool_call(aab_path_from_context, apk_output_file_path)
64+
run_described_fastlane_action(
6565
apk_output_file_path: apk_output_file_path
6666
)
6767

68-
expected_command = generate_command(aab_file_path: aab_path_from_context,
69-
apk_output_file_path: apk_output_file_path)
70-
expect(cmd).to eq(expected_command)
68+
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_AAB_OUTPUT_PATH] = nil
7169
end
7270

73-
it 'calls the `bundletool` command with the correct arguments and use the path to the AAB from the lane context if the SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS key is set' do
74-
all_aab_paths_from_context = ['first/path/from/context/app.aab']
75-
76-
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = all_aab_paths_from_context
71+
it 'infers the AAB path from lane context if `SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS` is set with only one value' do
72+
aab_paths_from_context = ['first/path/from/context/app.aab']
73+
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = aab_paths_from_context
7774

78-
cmd = run_described_fastlane_action(
75+
expect_bundletool_call(aab_paths_from_context.first, apk_output_file_path)
76+
run_described_fastlane_action(
7977
apk_output_file_path: apk_output_file_path
8078
)
8179

82-
expected_command = generate_command(aab_file_path: all_aab_paths_from_context.first,
83-
apk_output_file_path: apk_output_file_path)
84-
expect(cmd).to eq(expected_command)
80+
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = nil
81+
end
82+
83+
it 'does not infer the AAB path from lane context if `SharedValues::GRADLE_AAB_OUTPUT_PATHS` has more than one value' do
84+
aab_paths_from_context = ['first/path/from/context/app.aab', 'second/path/from/context/app.aab']
85+
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = aab_paths_from_context
86+
87+
expect do
88+
run_described_fastlane_action(
89+
apk_output_file_path: apk_output_file_path
90+
)
91+
end.to raise_error(described_class::NO_AAB_ERROR_MESSAGE)
92+
93+
Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = nil
94+
end
95+
96+
it 'infers the output path if none is provided' do
97+
inferred_apk_path = File.join(File.dirname(aab_file_path), "#{File.basename(aab_file_path, '.aab')}.apk")
98+
expect_bundletool_call(aab_file_path, inferred_apk_path)
99+
100+
output = run_described_fastlane_action(
101+
aab_file_path: aab_file_path
102+
)
103+
104+
expect(output).to eq(inferred_apk_path)
105+
end
106+
107+
it 'infers the output file name if output path is a directory' do
108+
in_tmp_dir do |output_dir|
109+
inferred_apk_path = File.join(output_dir, "#{File.basename(aab_file_path, '.aab')}.apk")
110+
expect_bundletool_call(aab_file_path, inferred_apk_path)
111+
112+
output = run_described_fastlane_action(
113+
aab_file_path: aab_file_path,
114+
apk_output_file_path: output_dir
115+
)
116+
117+
expect(output).to eq(inferred_apk_path)
118+
end
119+
end
120+
end
121+
122+
describe 'error handling' do
123+
it 'errors if bundletool is not installed' do
124+
allow(Fastlane::Action).to receive('sh').with('command', '-v', 'bundletool', any_args).and_raise
125+
expect(Fastlane::UI).to receive(:user_error!).with(described_class::MISSING_BUNDLETOOL_ERROR_MESSAGE).and_raise
126+
127+
expect do
128+
run_described_fastlane_action(
129+
aab_file_path: aab_file_path,
130+
apk_output_file_path: apk_output_file_path
131+
)
132+
end.to raise_error(RuntimeError)
133+
end
134+
135+
it 'errors if no input AAB file was provided nor can be inferred' do
136+
expect(Fastlane::Action).to receive('sh').with('command', '-v', 'bundletool', any_args)
137+
expect(Fastlane::UI).to receive(:user_error!).with(described_class::NO_AAB_ERROR_MESSAGE).and_raise
138+
139+
expect do
140+
run_described_fastlane_action(
141+
apk_output_file_path: apk_output_file_path
142+
)
143+
end.to raise_error(RuntimeError)
144+
end
145+
146+
it 'errors if the provided input AAB file does not exist' do
147+
expect(Fastlane::Action).to receive('sh').with('command', '-v', 'bundletool', any_args)
148+
allow(File).to receive(:file?).with(aab_file_path).and_return(false)
149+
expect(Fastlane::UI).to receive(:user_error!).with("The file `#{aab_file_path}` was not found. Please provide a path to an existing file.").and_raise
150+
151+
expect do
152+
run_described_fastlane_action(
153+
aab_file_path: aab_file_path,
154+
apk_output_file_path: apk_output_file_path
155+
)
156+
end.to raise_error(RuntimeError)
85157
end
86158
end
87159
end

0 commit comments

Comments
 (0)