Coverage for tests/endpoints/tests_builds.py: 100%

110 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2025-08-26 22:06 +0000

1from unittest.mock import patch, MagicMock 

2from tests.endpoints.endpoint_testing import TestEndpoints 

3 

4 

5class TestGetSnapRepo(TestEndpoints): 

6 def setUp(self): 

7 super().setUp() 

8 self.snap_name = "test-snap" 

9 self.endpoint_url = f"/api/{self.snap_name}/repo" 

10 

11 @patch("webapp.endpoints.builds.GitHub") 

12 @patch("webapp.endpoints.builds.launchpad") 

13 @patch("webapp.endpoints.builds.dashboard") 

14 def test_get_snap_repo_with_existing_lp_snap_success( 

15 self, mock_dashboard, mock_launchpad, mock_github_class 

16 ): 

17 """Test get_snap_repo when snap exists in Launchpad and GitHub 

18 repo is accessible""" 

19 # Mock dashboard responses 

20 mock_snap_info = {"snap_name": self.snap_name} 

21 mock_dashboard.get_snap_info.return_value = mock_snap_info 

22 mock_dashboard.get_package_upload_macaroon.return_value = None 

23 

24 # Mock Launchpad response 

25 mock_lp_snap = { 

26 "git_repository_url": "https://github.com/test-owner/test-repo" 

27 } 

28 mock_launchpad.get_snap_by_store_name.return_value = mock_lp_snap 

29 

30 # Mock GitHub responses 

31 mock_github = MagicMock() 

32 mock_github.check_if_repo_exists.return_value = True 

33 mock_github.get_user.return_value = {"login": "test-user"} 

34 mock_github.get_orgs.return_value = [{"login": "test-org"}] 

35 mock_github_class.return_value = mock_github 

36 

37 response = self.client.get(self.endpoint_url) 

38 data = response.get_json() 

39 

40 self.assertEqual(response.status_code, 200) 

41 self.assertTrue(data["success"]) 

42 self.assertEqual(data["message"], "") 

43 self.assertEqual( 

44 data["data"]["github_repository"], "test-owner/test-repo" 

45 ) 

46 self.assertEqual(data["data"]["github_user"], {"login": "test-user"}) 

47 self.assertEqual(data["data"]["github_orgs"], [{"login": "test-org"}]) 

48 

49 # Verify dashboard methods were called 

50 mock_dashboard.get_snap_info.assert_called_once() 

51 mock_dashboard.get_package_upload_macaroon.assert_called_once() 

52 

53 @patch("webapp.endpoints.builds.GitHub") 

54 @patch("webapp.endpoints.builds.launchpad") 

55 @patch("webapp.endpoints.builds.dashboard") 

56 def test_get_snap_repo_with_revoked_github_access( 

57 self, mock_dashboard, mock_launchpad, mock_github_class 

58 ): 

59 """Test get_snap_repo when GitHub repo access has been revoked""" 

60 # Mock dashboard responses 

61 mock_snap_info = {"snap_name": self.snap_name} 

62 mock_dashboard.get_snap_info.return_value = mock_snap_info 

63 mock_dashboard.get_package_upload_macaroon.return_value = None 

64 

65 # Mock Launchpad response 

66 mock_lp_snap = { 

67 "git_repository_url": "https://github.com/test-owner/test-repo" 

68 } 

69 mock_launchpad.get_snap_by_store_name.return_value = mock_lp_snap 

70 

71 # Mock GitHub responses - repo doesn't exist (revoked access) 

72 mock_github = MagicMock() 

73 mock_github.check_if_repo_exists.return_value = False 

74 mock_github.get_user.return_value = {"login": "test-user"} 

75 mock_github.get_orgs.return_value = [{"login": "test-org"}] 

76 mock_github_class.return_value = mock_github 

77 

78 response = self.client.get(self.endpoint_url) 

79 data = response.get_json() 

80 

81 self.assertEqual(response.status_code, 200) 

82 self.assertFalse(data["data"]["success"]) 

83 self.assertEqual(data["data"]["message"], "This app has been revoked") 

84 self.assertEqual( 

85 data["data"]["github_repository"], "test-owner/test-repo" 

86 ) 

87 

88 @patch("webapp.endpoints.builds.GitHub") 

89 @patch("webapp.endpoints.builds.launchpad") 

90 @patch("webapp.endpoints.builds.dashboard") 

91 def test_get_snap_repo_without_lp_snap_authorized( 

92 self, mock_dashboard, mock_launchpad, mock_github_class 

93 ): 

94 """Test get_snap_repo when no Launchpad snap exists but user is 

95 authorized""" 

96 # Mock dashboard responses 

97 mock_snap_info = {"snap_name": self.snap_name} 

98 mock_dashboard.get_snap_info.return_value = mock_snap_info 

99 mock_dashboard.get_package_upload_macaroon.return_value = None 

100 

101 # Mock Launchpad response - no snap found 

102 mock_launchpad.get_snap_by_store_name.return_value = None 

103 

104 # Mock GitHub responses 

105 mock_github = MagicMock() 

106 mock_github.get_user.return_value = {"login": "test-user"} 

107 mock_github.get_orgs.return_value = [{"login": "test-org"}] 

108 mock_github_class.return_value = mock_github 

109 

110 response = self.client.get(self.endpoint_url) 

111 data = response.get_json() 

112 

113 self.assertEqual(response.status_code, 200) 

114 self.assertTrue(data["success"]) 

115 self.assertEqual(data["message"], "") 

116 self.assertIsNone(data["data"]["github_repository"]) 

117 self.assertEqual(data["data"]["github_user"], {"login": "test-user"}) 

118 self.assertEqual(data["data"]["github_orgs"], [{"login": "test-org"}]) 

119 

120 @patch("webapp.endpoints.builds.GitHub") 

121 @patch("webapp.endpoints.builds.launchpad") 

122 @patch("webapp.endpoints.builds.dashboard") 

123 def test_get_snap_repo_without_lp_snap_unauthorized( 

124 self, mock_dashboard, mock_launchpad, mock_github_class 

125 ): 

126 """Test get_snap_repo when no Launchpad snap exists and user is 

127 unauthorized""" 

128 # Mock dashboard responses 

129 mock_snap_info = {"snap_name": self.snap_name} 

130 mock_dashboard.get_snap_info.return_value = mock_snap_info 

131 mock_dashboard.get_package_upload_macaroon.return_value = None 

132 

133 # Mock Launchpad response - no snap found 

134 mock_launchpad.get_snap_by_store_name.return_value = None 

135 

136 # Mock GitHub responses - no user (unauthorized) 

137 mock_github = MagicMock() 

138 mock_github.get_user.return_value = None 

139 mock_github_class.return_value = mock_github 

140 

141 response = self.client.get(self.endpoint_url) 

142 data = response.get_json() 

143 

144 self.assertEqual(response.status_code, 200) 

145 self.assertFalse(data["data"]["success"]) 

146 self.assertEqual(data["data"]["message"], "Unauthorized") 

147 self.assertIsNone(data["data"]["github_repository"]) 

148 

149 @patch( 

150 "webapp.endpoints.builds.GITHUB_SNAPCRAFT_USER_TOKEN", "fallback-token" 

151 ) 

152 @patch("webapp.endpoints.builds.GitHub") 

153 @patch("webapp.endpoints.builds.launchpad") 

154 @patch("webapp.endpoints.builds.dashboard") 

155 def test_get_snap_repo_uses_fallback_token_when_no_session_token( 

156 self, mock_dashboard, mock_launchpad, mock_github_class 

157 ): 

158 """Test get_snap_repo uses fallback token when no GitHub token 

159 in session""" 

160 # Mock dashboard responses 

161 mock_snap_info = {"snap_name": self.snap_name} 

162 mock_dashboard.get_snap_info.return_value = mock_snap_info 

163 mock_dashboard.get_package_upload_macaroon.return_value = None 

164 

165 # Mock Launchpad response 

166 mock_lp_snap = { 

167 "git_repository_url": "https://github.com/test-owner/test-repo" 

168 } 

169 mock_launchpad.get_snap_by_store_name.return_value = mock_lp_snap 

170 

171 # Mock GitHub responses 

172 mock_github = MagicMock() 

173 mock_github.check_if_repo_exists.return_value = True 

174 mock_github.get_user.return_value = {"login": "snapcraft-user"} 

175 mock_github.get_orgs.return_value = [] 

176 mock_github_class.return_value = mock_github 

177 

178 # Clear GitHub token from session 

179 with self.client.session_transaction() as session: 

180 session.pop("github_auth_secret", None) 

181 

182 response = self.client.get(self.endpoint_url) 

183 data = response.get_json() 

184 

185 self.assertEqual(response.status_code, 200) 

186 self.assertTrue(data["success"]) 

187 

188 # Verify GitHub was initialized with fallback token 

189 mock_github_class.assert_called_with("fallback-token")