Coverage for arbejdstimer/api.py: 100.00%

36 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2023-01-02 19:01 +0100

1# -*- coding: utf-8 -*- 

2# pylint: disable=expression-not-assigned,line-too-long 

3"""Working hours (Danish arbejdstimer) or not? API model.""" 

4from __future__ import annotations 

5 

6from datetime import date 

7from enum import Enum 

8from typing import Annotated, List, Optional, no_type_check 

9 

10from pydantic import BaseModel, Field, validator 

11 

12 

13class Application(Enum): 

14 arbejdstimer = 'arbejdstimer' 

15 

16 

17class Operator(Enum): 

18 and_ = 'and' 

19 or_ = 'or' 

20 xor = 'xor' 

21 

22 

23class Hour(BaseModel): 

24 __root__: Annotated[int, Field(ge=0.0, le=23.0)] 

25 

26 

27class WorkingHours(BaseModel): 

28 __root__: Annotated[ 

29 List[Hour], 

30 Field( 

31 description='Inclusive range of 24 hour start and end integer values.', 

32 max_items=2, 

33 min_items=2, 

34 title='Working Hours', 

35 ), 

36 ] 

37 

38 

39class Dates(BaseModel): 

40 __root__: Annotated[ 

41 List[date], 

42 Field( 

43 description='Two dates are an inclusive range and 1, 3, or more dates represent a set of dates.', 

44 min_items=1, 

45 title='Dates - Range or Set', 

46 ), 

47 ] 

48 

49 @no_type_check 

50 @validator('__root__') 

51 @classmethod 

52 def is_unique(cls, v): 

53 if v and 1 < len(v) != len(set(v)): 

54 raise ValueError('dates must be unique') 

55 return v 

56 

57 

58class Holiday(BaseModel): 

59 label: Annotated[Optional[str], Field(examples=['public holiday'])] = '' 

60 at: Dates 

61 

62 

63class Holidays(BaseModel): 

64 __root__: Annotated[ 

65 List[Holiday], 

66 Field( 

67 description='Optionally labeled dates of non-working days.', 

68 min_items=0, 

69 title='Holidays', 

70 ), 

71 ] 

72 

73 

74class Arbejdstimer(BaseModel): 

75 api: Annotated[ 

76 Optional[int], 

77 Field( 

78 description='API version of the application this configuration targets.', 

79 title='API Version', 

80 ), 

81 ] = 1 

82 application: Annotated[ 

83 Optional[Application], 

84 Field( 

85 description='Name of the application this configuration targets.', 

86 title='Application Name', 

87 ), 

88 ] = Application.arbejdstimer 

89 operator: Annotated[ 

90 Operator, 

91 Field( 

92 description='Logic combining the given specific values with the application defaults.', 

93 title='Logic for Combination with Default Values', 

94 ), 

95 ] 

96 holidays: Optional[Holidays] = None 

97 working_hours: Optional[WorkingHours] = None