167 lines
4.9 KiB
Dart
167 lines
4.9 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/testing.dart';
|
|
|
|
import 'package:appsok/src/models/jenkins_build.dart';
|
|
import 'package:appsok/src/services/artifact_staging_service.dart';
|
|
import 'package:appsok/src/services/jenkins_artifact_session.dart';
|
|
import 'package:appsok/src/services/jenkins_client.dart';
|
|
import 'package:appsok/src/services/token_store.dart';
|
|
|
|
void main() {
|
|
const credentials = JenkinsCredentials(username: 'user', apiToken: 'token');
|
|
const baseUrl = 'https://jenkins.example';
|
|
|
|
setUp(() {
|
|
FlutterSecureStorage.setMockInitialValues({});
|
|
});
|
|
|
|
test('restore validates stored session with current user api', () async {
|
|
FlutterSecureStorage.setMockInitialValues({
|
|
'jenkins.baseUrl': baseUrl,
|
|
'jenkins.username': credentials.username,
|
|
'jenkins.apiToken': credentials.apiToken,
|
|
});
|
|
|
|
Uri? capturedUri;
|
|
Map<String, String>? capturedHeaders;
|
|
|
|
final session = JenkinsArtifactSession(
|
|
store: TokenStore(),
|
|
client: JenkinsClient(
|
|
client: MockClient((request) async {
|
|
capturedUri = request.url;
|
|
capturedHeaders = request.headers;
|
|
|
|
if (request.url.path.endsWith('whoAmI/api/json')) {
|
|
return http.Response(jsonEncode({'id': 'user'}), 200);
|
|
}
|
|
|
|
return http.Response('unexpected', 400);
|
|
}),
|
|
),
|
|
stager: ArtifactStagingService(),
|
|
);
|
|
|
|
final restored = await session.restore();
|
|
|
|
expect(restored, isTrue);
|
|
expect(capturedUri?.path, '/whoAmI/api/json');
|
|
expect(
|
|
capturedHeaders?['Authorization'],
|
|
'Basic ${base64Encode(utf8.encode('user:token'))}',
|
|
);
|
|
});
|
|
|
|
test('loadJobs delegates to JenkinsClient with stored base url and credentials', () async {
|
|
FlutterSecureStorage.setMockInitialValues({
|
|
'jenkins.baseUrl': baseUrl,
|
|
'jenkins.username': credentials.username,
|
|
'jenkins.apiToken': credentials.apiToken,
|
|
});
|
|
|
|
Uri? jobsUri;
|
|
|
|
final session = JenkinsArtifactSession(
|
|
store: TokenStore(),
|
|
client: JenkinsClient(
|
|
client: MockClient((request) async {
|
|
if (request.url.path.endsWith('whoAmI/api/json')) {
|
|
return http.Response(jsonEncode({'id': 'user'}), 200);
|
|
}
|
|
|
|
if (request.url.path.endsWith('api/json')) {
|
|
jobsUri = request.url;
|
|
return http.Response(
|
|
jsonEncode({'jobs': []}),
|
|
200,
|
|
);
|
|
}
|
|
|
|
return http.Response('unexpected', 400);
|
|
}),
|
|
),
|
|
stager: ArtifactStagingService(),
|
|
);
|
|
|
|
await session.restore();
|
|
await session.loadJobs();
|
|
|
|
expect(jobsUri, isNotNull);
|
|
expect(jobsUri?.path, '/api/json');
|
|
expect(jobsUri?.host, 'jenkins.example');
|
|
});
|
|
|
|
test('downloadArtifact builds Jenkins artifact URL from build url and relative path',
|
|
() async {
|
|
FlutterSecureStorage.setMockInitialValues({
|
|
'jenkins.baseUrl': baseUrl,
|
|
'jenkins.username': credentials.username,
|
|
'jenkins.apiToken': credentials.apiToken,
|
|
});
|
|
|
|
Uri? artifactUri;
|
|
|
|
final session = JenkinsArtifactSession(
|
|
store: TokenStore(),
|
|
client: JenkinsClient(
|
|
client: MockClient((request) async {
|
|
if (request.url.path.endsWith('whoAmI/api/json')) {
|
|
return http.Response(jsonEncode({'id': 'user'}), 200);
|
|
}
|
|
|
|
if (request.url.path.endsWith('artifact/file.apk')) {
|
|
artifactUri = request.url;
|
|
return http.Response.bytes([], 200);
|
|
}
|
|
|
|
if (request.url.path.endsWith('api/json')) {
|
|
return http.Response(jsonEncode({'jobs': []}), 200);
|
|
}
|
|
|
|
return http.Response('unexpected', 400);
|
|
}),
|
|
),
|
|
stager: ArtifactStagingService(),
|
|
);
|
|
|
|
await session.restore();
|
|
|
|
final task = session.downloadArtifact(
|
|
JenkinsBuild(
|
|
number: 1,
|
|
jobName: 'app',
|
|
url: Uri.parse('$baseUrl/job/app/1/'),
|
|
startedAt: DateTime(2026),
|
|
result: 'SUCCESS',
|
|
artifacts: const [
|
|
BuildArtifact(fileName: 'app.apk', relativePath: 'artifact/file.apk'),
|
|
],
|
|
),
|
|
const BuildArtifact(fileName: 'file.apk', relativePath: 'artifact/file.apk'),
|
|
);
|
|
|
|
await task.events.toList();
|
|
|
|
expect(artifactUri, isNotNull);
|
|
expect(artifactUri?.path, '/job/app/1/artifact/artifact/file.apk');
|
|
});
|
|
|
|
test('returns unavailable state when session config is missing', () async {
|
|
final session = JenkinsArtifactSession(
|
|
store: TokenStore(),
|
|
client: JenkinsClient(
|
|
client: MockClient((_) async => http.Response('', 200)),
|
|
),
|
|
stager: ArtifactStagingService(),
|
|
);
|
|
|
|
final restored = await session.restore();
|
|
|
|
expect(restored, isFalse);
|
|
expect(session.isRestored, isFalse);
|
|
});
|
|
}
|