157 lines
4.3 KiB
Dart
157 lines
4.3 KiB
Dart
import 'dart:convert';
|
|
|
|
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/jenkins_client.dart';
|
|
|
|
void main() {
|
|
const credentials = JenkinsCredentials(username: 'user', apiToken: 'token');
|
|
final baseUrl = Uri.parse('https://jenkins.example/');
|
|
|
|
group('JenkinsJob.fromJson', () {
|
|
test('parses jenkins jobs from api response', () {
|
|
final json = {
|
|
'name': 'my-app',
|
|
'fullName': 'my-app',
|
|
'url': 'https://jenkins.example/job/my-app/',
|
|
'color': 'blue',
|
|
'_class': 'hudson.model.FreeStyleProject',
|
|
};
|
|
|
|
final job = JenkinsJob.fromJson(json);
|
|
|
|
expect(job.name, 'my-app');
|
|
expect(job.fullName, 'my-app');
|
|
expect(job.url, Uri.parse('https://jenkins.example/job/my-app/'));
|
|
expect(job.color, 'blue');
|
|
expect(job.isFolder, isFalse);
|
|
});
|
|
|
|
test('marks folder jobs from _class', () {
|
|
final json = {
|
|
'name': 'team-folder',
|
|
'fullName': 'team-folder',
|
|
'url': 'https://jenkins.example/job/team-folder/',
|
|
'_class': 'com.cloudbees.hudson.plugins.folder.Folder',
|
|
};
|
|
|
|
final job = JenkinsJob.fromJson(json);
|
|
|
|
expect(job.name, 'team-folder');
|
|
expect(job.isFolder, isTrue);
|
|
expect(job.color, isNull);
|
|
});
|
|
|
|
test('parses job with minimal fields', () {
|
|
final json = {
|
|
'name': 'minimal-job',
|
|
'url': 'https://jenkins.example/job/minimal-job/',
|
|
};
|
|
|
|
final job = JenkinsJob.fromJson(json);
|
|
|
|
expect(job.name, 'minimal-job');
|
|
expect(job.fullName, isNull);
|
|
expect(job.color, isNull);
|
|
expect(job.isFolder, isFalse);
|
|
});
|
|
});
|
|
|
|
group('JenkinsClient.fetchJobs', () {
|
|
test('fetchJobs requests root api json with job tree', () async {
|
|
Uri? capturedUri;
|
|
Map<String, String>? capturedHeaders;
|
|
|
|
final client = JenkinsClient(
|
|
client: MockClient((request) async {
|
|
capturedUri = request.url;
|
|
capturedHeaders = request.headers;
|
|
return http.Response(
|
|
jsonEncode({
|
|
'jobs': [
|
|
{
|
|
'name': 'app-release',
|
|
'fullName': 'app-release',
|
|
'url': 'https://jenkins.example/job/app-release/',
|
|
'color': 'blue',
|
|
'_class': 'hudson.model.FreeStyleProject',
|
|
},
|
|
],
|
|
}),
|
|
200,
|
|
);
|
|
}),
|
|
);
|
|
|
|
final jobs = await client.fetchJobs(
|
|
baseUrl: baseUrl,
|
|
credentials: credentials,
|
|
);
|
|
|
|
expect(jobs, hasLength(1));
|
|
expect(jobs.first.name, 'app-release');
|
|
expect(capturedUri?.path, contains('api/json'));
|
|
expect(
|
|
capturedUri?.queryParameters['tree'],
|
|
'jobs[name,fullName,url,color,_class]',
|
|
);
|
|
|
|
final expectedAuth = 'Basic ${base64Encode(utf8.encode('user:token'))}';
|
|
expect(capturedHeaders?['Authorization'], expectedAuth);
|
|
});
|
|
|
|
test('fetchJobs returns empty list when jobs key is missing', () async {
|
|
final client = JenkinsClient(
|
|
client: MockClient(
|
|
(_) async =>
|
|
http.Response(jsonEncode({'_class': 'hudson.model.Hudson'}), 200),
|
|
),
|
|
);
|
|
|
|
final jobs = await client.fetchJobs(
|
|
baseUrl: baseUrl,
|
|
credentials: credentials,
|
|
);
|
|
|
|
expect(jobs, isEmpty);
|
|
});
|
|
|
|
test('fetchJobs returns empty list when jobs is empty array', () async {
|
|
final client = JenkinsClient(
|
|
client: MockClient(
|
|
(_) async => http.Response(jsonEncode({'jobs': []}), 200),
|
|
),
|
|
);
|
|
|
|
final jobs = await client.fetchJobs(
|
|
baseUrl: baseUrl,
|
|
credentials: credentials,
|
|
);
|
|
|
|
expect(jobs, isEmpty);
|
|
});
|
|
|
|
test(
|
|
'fetchJobs throws JenkinsClientException on forbidden response',
|
|
() async {
|
|
final client = JenkinsClient(
|
|
client: MockClient((_) async => http.Response('Forbidden', 403)),
|
|
);
|
|
|
|
expect(
|
|
() => client.fetchJobs(baseUrl: baseUrl, credentials: credentials),
|
|
throwsA(
|
|
isA<JenkinsClientException>().having(
|
|
(e) => e.statusCode,
|
|
'statusCode',
|
|
403,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
});
|
|
}
|