Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions app/test/groups/group_permission_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2026 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:flutter_test/flutter_test.dart';
import 'package:group_domain_models/group_domain_models.dart';
import 'package:sharezone/groups/group_permission.dart';

void main() {
group('HasRolePermission', () {
group('hasPermission for administration', () {
test('should be true for owner', () {
expect(MemberRole.owner.hasPermission(GroupPermission.administration),
isTrue);
});

test('should be true for admin', () {
expect(MemberRole.admin.hasPermission(GroupPermission.administration),
isTrue);
});

test('should be false for creator', () {
expect(MemberRole.creator.hasPermission(GroupPermission.administration),
isFalse);
});

test('should be false for standard', () {
expect(
MemberRole.standard.hasPermission(GroupPermission.administration),
isFalse);
});
});

group('hasPermission for contentCreation', () {
test('should be true for owner', () {
expect(MemberRole.owner.hasPermission(GroupPermission.contentCreation),
isTrue);
});

test('should be true for admin', () {
expect(MemberRole.admin.hasPermission(GroupPermission.contentCreation),
isTrue);
});

test('should be true for creator', () {
expect(
MemberRole.creator.hasPermission(GroupPermission.contentCreation),
isTrue);
});

test('should be false for standard', () {
expect(
MemberRole.standard.hasPermission(GroupPermission.contentCreation),
isFalse);
});
});
Comment on lines +15 to +60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The tests in these groups are repetitive. You can use a data-driven approach with a map of test cases to make the code more concise and maintainable. This pattern can also be applied to the isUserAdminOrOwnerOfGroup test group.

    group('hasPermission for administration', () {
      final testCases = <MemberRole, bool>{
        MemberRole.owner: true,
        MemberRole.admin: true,
        MemberRole.creator: false,
        MemberRole.standard: false,
      };

      for (final entry in testCases.entries) {
        test('should be ${entry.value} for ${entry.key.name}', () {
          expect(
            entry.key.hasPermission(GroupPermission.administration),
            entry.value,
          );
        });
      }
    });

    group('hasPermission for contentCreation', () {
      final testCases = <MemberRole, bool>{
        MemberRole.owner: true,
        MemberRole.admin: true,
        MemberRole.creator: true,
        MemberRole.standard: false,
      };

      for (final entry in testCases.entries) {
        test('should be ${entry.value} for ${entry.key.name}', () {
          expect(
            entry.key.hasPermission(GroupPermission.contentCreation),
            entry.value,
          );
        });
      }
    });

});

group('isUserAdminOrOwnerOfGroup', () {
test('should be true for owner', () {
expect(isUserAdminOrOwnerOfGroup(MemberRole.owner), isTrue);
});

test('should be true for admin', () {
expect(isUserAdminOrOwnerOfGroup(MemberRole.admin), isTrue);
});

test('should be false for creator', () {
expect(isUserAdminOrOwnerOfGroup(MemberRole.creator), isFalse);
});

test('should be false for standard', () {
expect(isUserAdminOrOwnerOfGroup(MemberRole.standard), isFalse);
});

test('should be false for null role', () {
expect(isUserAdminOrOwnerOfGroup(null), isFalse);
});
});
}
93 changes: 93 additions & 0 deletions app/test/submissions/submission_permissions_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) 2026 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:flutter_test/flutter_test.dart';
import 'package:group_domain_models/group_domain_models.dart';
import 'package:hausaufgabenheft_logik/hausaufgabenheft_logik.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:sharezone/submissions/submission_permissions.dart';
import 'package:sharezone/util/api/course_gateway.dart';
import 'package:user/user.dart';

@GenerateNiceMocks([MockSpec<CourseGateway>()])
import 'submission_permissions_test.mocks.dart';

void main() {
late MockCourseGateway mockCourseGateway;

setUp(() {
mockCourseGateway = MockCourseGateway();
});

group('SubmissionPermissions.isAllowedToViewSubmittedPermissions', () {
test('should allow when user is teacher and is admin in course', () async {
when(mockCourseGateway.getRoleFromCourseNoSync(any))
.thenReturn(MemberRole.admin);
final stream = Stream.value(TypeOfUser.teacher);
final permissions = SubmissionPermissions(stream, mockCourseGateway);
final homework = HomeworkDto.create(courseID: 'course1');

final result =
await permissions.isAllowedToViewSubmittedPermissions(homework);

expect(result, isTrue);
});

test('should allow when user is teacher and is owner in course', () async {
when(mockCourseGateway.getRoleFromCourseNoSync(any))
.thenReturn(MemberRole.owner);
final stream = Stream.value(TypeOfUser.teacher);
final permissions = SubmissionPermissions(stream, mockCourseGateway);
final homework = HomeworkDto.create(courseID: 'course1');

final result =
await permissions.isAllowedToViewSubmittedPermissions(homework);

expect(result, isTrue);
});

test('should deny when user is teacher but only standard in course', () async {
when(mockCourseGateway.getRoleFromCourseNoSync(any))
.thenReturn(MemberRole.standard);
final stream = Stream.value(TypeOfUser.teacher);
final permissions = SubmissionPermissions(stream, mockCourseGateway);
final homework = HomeworkDto.create(courseID: 'course1');

final result =
await permissions.isAllowedToViewSubmittedPermissions(homework);

expect(result, isFalse);
});

test('should deny when user is student even if admin in course', () async {
when(mockCourseGateway.getRoleFromCourseNoSync(any))
.thenReturn(MemberRole.admin);
final stream = Stream.value(TypeOfUser.student);
final permissions = SubmissionPermissions(stream, mockCourseGateway);
final homework = HomeworkDto.create(courseID: 'course1');

final result =
await permissions.isAllowedToViewSubmittedPermissions(homework);

expect(result, isFalse);
});

test('should deny when course role is null (defaults to standard)', () async {
when(mockCourseGateway.getRoleFromCourseNoSync(any)).thenReturn(null);
final stream = Stream.value(TypeOfUser.teacher);
final permissions = SubmissionPermissions(stream, mockCourseGateway);
final homework = HomeworkDto.create(courseID: 'course1');

final result =
await permissions.isAllowedToViewSubmittedPermissions(homework);

expect(result, isFalse);
});
});
Comment on lines +28 to +92

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The tests in this group are very similar and contain duplicated code. You can refactor this using a data-driven approach to make the tests more concise and easier to maintain and extend.

  group('SubmissionPermissions.isAllowedToViewSubmittedPermissions', () {
    final homework = HomeworkDto.create(courseID: 'course1');

    final testCases = <String, ({TypeOfUser userType, MemberRole? role, bool expected})>{
      'allow when user is teacher and is admin in course': (
        userType: TypeOfUser.teacher,
        role: MemberRole.admin,
        expected: true,
      ),
      'allow when user is teacher and is owner in course': (
        userType: TypeOfUser.teacher,
        role: MemberRole.owner,
        expected: true,
      ),
      'deny when user is teacher but only standard in course': (
        userType: TypeOfUser.teacher,
        role: MemberRole.standard,
        expected: false,
      ),
      'deny when user is student even if admin in course': (
        userType: TypeOfUser.student,
        role: MemberRole.admin,
        expected: false,
      ),
      'deny when course role is null (defaults to standard)': (
        userType: TypeOfUser.teacher,
        role: null,
        expected: false,
      ),
    };

    for (final entry in testCases.entries) {
      test('should ${entry.key}', () async {
        when(mockCourseGateway.getRoleFromCourseNoSync(any))
            .thenReturn(entry.value.role);
        final stream = Stream.value(entry.value.userType);
        final permissions = SubmissionPermissions(stream, mockCourseGateway);

        final result =
            await permissions.isAllowedToViewSubmittedPermissions(homework);

        expect(result, entry.value.expected);
      });
    }
  });

}
Loading
Loading