Coverage for ingadhoc-odoo-saas-adhoc / saas_provider_upgrade / tests / test_upload_changes.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-09 18:15 +0000

1from odoo.exceptions import ValidationError 

2 

3from .test_provider_upgrade_base import TestProviderUpgradeCommon 

4 

5 

6class TestUploadChanges(TestProviderUpgradeCommon): 

7 """ 

8 Test cases for the saas.upgrade.upload.changes model. 

9 

10 Validates: 

11 - CRUD operations 

12 - record_id constraint (must be > 0) 

13 - edit() action returns correct window action 

14 - change_type selection behavior 

15 """ 

16 

17 @classmethod 

18 def setUpClass(cls): 

19 super().setUpClass() 

20 cls.UploadChanges = cls.env["saas.upgrade.upload.changes"] 

21 

22 def test_create_upload_changes_code_type(self): 

23 """Test creating an upload change record with 'code' type.""" 

24 upload_change = self.UploadChanges.create( 

25 { 

26 "name": "Test Code Change", 

27 "change_type": "code", 

28 "record_id": 1, 

29 "ticket_id": self.upgrade_ticket.id, 

30 "code": "print('Hello World')", 

31 } 

32 ) 

33 self.assertEqual(upload_change.name, "Test Code Change") 

34 self.assertEqual(upload_change.change_type, "code") 

35 self.assertEqual(upload_change.record_id, 1) 

36 self.assertEqual(upload_change.ticket_id, self.upgrade_ticket) 

37 self.assertEqual(upload_change.code, "print('Hello World')") 

38 

39 def test_create_upload_changes_attachment_type(self): 

40 """Test creating an upload change record with 'attachment' type.""" 

41 upload_change = self.UploadChanges.create( 

42 { 

43 "name": "Test Attachment Change", 

44 "change_type": "attachment", 

45 "record_id": 100, 

46 "ticket_id": self.upgrade_ticket.id, 

47 } 

48 ) 

49 self.assertEqual(upload_change.name, "Test Attachment Change") 

50 self.assertEqual(upload_change.change_type, "attachment") 

51 self.assertEqual(upload_change.record_id, 100) 

52 

53 def test_record_id_constraint_zero(self): 

54 """Test that record_id cannot be zero - ValidationError expected.""" 

55 with self.assertRaises(ValidationError): 

56 self.UploadChanges.create( 

57 { 

58 "name": "Invalid Record ID Zero", 

59 "change_type": "code", 

60 "record_id": 0, 

61 "ticket_id": self.upgrade_ticket.id, 

62 } 

63 ) 

64 

65 def test_record_id_constraint_negative(self): 

66 """Test that record_id cannot be negative - ValidationError expected.""" 

67 with self.assertRaises(ValidationError): 

68 self.UploadChanges.create( 

69 { 

70 "name": "Invalid Record ID Negative", 

71 "change_type": "code", 

72 "record_id": -5, 

73 "ticket_id": self.upgrade_ticket.id, 

74 } 

75 ) 

76 

77 def test_record_id_constraint_positive(self): 

78 """Test that record_id can be a positive integer.""" 

79 upload_change = self.UploadChanges.create( 

80 { 

81 "name": "Valid Record ID", 

82 "change_type": "code", 

83 "record_id": 42, 

84 "ticket_id": self.upgrade_ticket.id, 

85 } 

86 ) 

87 self.assertEqual(upload_change.record_id, 42) 

88 

89 def test_ticket_cascade_delete(self): 

90 """Test that upload changes are deleted when ticket is deleted (ondelete='cascade').""" 

91 # Create a new project and upgrade type combination to avoid unique constraint 

92 test_project = ( 

93 self.env["project.project"] 

94 .with_context(mail_create_nolog=True) 

95 .create( 

96 { 

97 "name": "Test Cascade Project", 

98 "partner_id": self.partner_upgrade_portal.id, 

99 "account_id": self.upgrade_analytic_account.id, 

100 } 

101 ) 

102 ) 

103 

104 test_ticket = self.env["helpdesk.ticket"].create( 

105 { 

106 "name": "Ticket to Delete", 

107 "team_id": self.upgrade_team.id, 

108 "upgrade_type_id": self.upgrade_type.id, 

109 "user_id": self.env.ref("base.user_admin").id, 

110 "partner_id": self.partner_upgrade_portal.id, 

111 "project_id": test_project.id, 

112 "main_database_id": self.upgrade_production_database.id, 

113 } 

114 ) 

115 cascade_change = self.UploadChanges.create( 

116 { 

117 "name": "Cascade Test Change", 

118 "change_type": "attachment", 

119 "record_id": 999, 

120 "ticket_id": test_ticket.id, 

121 } 

122 ) 

123 cascade_change_id = cascade_change.id 

124 

125 # Delete the ticket 

126 test_ticket.unlink() 

127 

128 # Verify the upload change was also deleted 

129 deleted_record = self.UploadChanges.search([("id", "=", cascade_change_id)]) 

130 self.assertFalse(deleted_record.exists(), "Upload change should be deleted when ticket is deleted") 

131 

132 def test_update_record_id_to_invalid(self): 

133 """Test that updating record_id to invalid value raises ValidationError.""" 

134 upload_change = self.UploadChanges.create( 

135 { 

136 "name": "Test Update Constraint", 

137 "change_type": "code", 

138 "record_id": 10, 

139 "ticket_id": self.upgrade_ticket.id, 

140 } 

141 ) 

142 with self.assertRaises(ValidationError): 

143 upload_change.write({"record_id": 0}) 

144 

145 def test_create_without_change_type(self): 

146 """Test creating upload change without change_type (selection field allows empty).""" 

147 upload_change = self.UploadChanges.create( 

148 { 

149 "name": "No Change Type", 

150 "record_id": 1, 

151 "ticket_id": self.upgrade_ticket.id, 

152 } 

153 ) 

154 self.assertFalse(upload_change.change_type) 

155 

156 def test_record_id_not_specified_defaults_to_zero(self): 

157 """Test behavior when record_id is not specified. 

158 

159 Note: When record_id is not specified, it defaults to 0 (Integer field default). 

160 The constraint `if rec.record_id <= 0` should catch this, but the constraint 

161 decorator only triggers when the field is explicitly written. This test 

162 documents that creating without record_id does NOT raise ValidationError, 

163 which may indicate the constraint should use `required=True` on the field 

164 or adjust the constraint to check on create as well. 

165 """ 

166 upload_change = self.UploadChanges.create( 

167 { 

168 "name": "No Record ID", 

169 "change_type": "code", 

170 "ticket_id": self.upgrade_ticket.id, 

171 } 

172 ) 

173 # Documents current behavior: record defaults to 0 without validation error 

174 self.assertEqual(upload_change.record_id, 0) 

175 

176 def test_code_field_with_multiline(self): 

177 """Test that code field accepts multiline Python code.""" 

178 multiline_code = """def test_function(): 

179 x = 1 

180 y = 2 

181 return x + y 

182""" 

183 upload_change = self.UploadChanges.create( 

184 { 

185 "name": "Multiline Code Test", 

186 "change_type": "code", 

187 "record_id": 1, 

188 "ticket_id": self.upgrade_ticket.id, 

189 "code": multiline_code, 

190 } 

191 ) 

192 self.assertEqual(upload_change.code, multiline_code)